mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-16 02:11:01 +00:00

The json/v2 prototype is still in flux and the API can/will change. Statically enforce that types implementing the v2 methods satisfy the correct interface so that changes to the signature can be statically detected by the compiler. Updates tailscale/corp#791 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package setting
|
|
|
|
import (
|
|
jsonv2 "github.com/go-json-experiment/json"
|
|
"github.com/go-json-experiment/json/jsontext"
|
|
"tailscale.com/types/opt"
|
|
)
|
|
|
|
// Summary is an immutable [PolicyScope] and [Origin].
|
|
type Summary struct {
|
|
data summary
|
|
}
|
|
|
|
type summary struct {
|
|
Scope opt.Value[PolicyScope] `json:",omitzero"`
|
|
Origin opt.Value[Origin] `json:",omitzero"`
|
|
}
|
|
|
|
// SummaryWith returns a [Summary] with the specified options.
|
|
func SummaryWith(opts ...SummaryOption) Summary {
|
|
var summary Summary
|
|
for _, o := range opts {
|
|
o.applySummaryOption(&summary)
|
|
}
|
|
return summary
|
|
}
|
|
|
|
// IsEmpty reports whether s is empty.
|
|
func (s Summary) IsEmpty() bool {
|
|
return s == Summary{}
|
|
}
|
|
|
|
// Scope reports the [PolicyScope] in s.
|
|
func (s Summary) Scope() opt.Value[PolicyScope] {
|
|
return s.data.Scope
|
|
}
|
|
|
|
// Origin reports the [Origin] in s.
|
|
func (s Summary) Origin() opt.Value[Origin] {
|
|
return s.data.Origin
|
|
}
|
|
|
|
// String implements [fmt.Stringer].
|
|
func (s Summary) String() string {
|
|
if s.IsEmpty() {
|
|
return "{Empty}"
|
|
}
|
|
if origin, ok := s.data.Origin.GetOk(); ok {
|
|
return origin.String()
|
|
}
|
|
return s.data.Scope.String()
|
|
}
|
|
|
|
var (
|
|
_ jsonv2.MarshalerTo = (*Summary)(nil)
|
|
_ jsonv2.UnmarshalerFrom = (*Summary)(nil)
|
|
)
|
|
|
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
|
func (s Summary) MarshalJSONTo(out *jsontext.Encoder) error {
|
|
return jsonv2.MarshalEncode(out, &s.data)
|
|
}
|
|
|
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
|
func (s *Summary) UnmarshalJSONFrom(in *jsontext.Decoder) error {
|
|
return jsonv2.UnmarshalDecode(in, &s.data)
|
|
}
|
|
|
|
// MarshalJSON implements [json.Marshaler].
|
|
func (s Summary) MarshalJSON() ([]byte, error) {
|
|
return jsonv2.Marshal(s) // uses MarshalJSONTo
|
|
}
|
|
|
|
// UnmarshalJSON implements [json.Unmarshaler].
|
|
func (s *Summary) UnmarshalJSON(b []byte) error {
|
|
return jsonv2.Unmarshal(b, s) // uses UnmarshalJSONFrom
|
|
}
|
|
|
|
// SummaryOption is an option that configures [Summary]
|
|
// The following are allowed options:
|
|
//
|
|
// - [Summary]
|
|
// - [PolicyScope]
|
|
// - [Origin]
|
|
type SummaryOption interface {
|
|
applySummaryOption(summary *Summary)
|
|
}
|
|
|
|
func (s PolicyScope) applySummaryOption(summary *Summary) {
|
|
summary.data.Scope.Set(s)
|
|
}
|
|
|
|
func (o Origin) applySummaryOption(summary *Summary) {
|
|
summary.data.Origin.Set(o)
|
|
if !summary.data.Scope.IsSet() {
|
|
summary.data.Scope.Set(o.Scope())
|
|
}
|
|
}
|
|
|
|
func (s Summary) applySummaryOption(summary *Summary) {
|
|
*summary = s
|
|
}
|