all: statically enforce json/v2 interface satisfaction (#15154)

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>
This commit is contained in:
Joe Tsai
2025-02-27 12:33:31 -08:00
committed by GitHub
parent f5522e62d1
commit 3d28aa19cb
9 changed files with 64 additions and 0 deletions

View File

@@ -13,6 +13,11 @@ import (
"tailscale.com/util/must"
)
var (
_ jsonv2.MarshalerTo = (*Value[bool])(nil)
_ jsonv2.UnmarshalerFrom = (*Value[bool])(nil)
)
type testStruct struct {
Int int `json:",omitempty,omitzero"`
Str string `json:",omitempty"`

View File

@@ -157,6 +157,11 @@ func (lv ListView[T]) Equal(lv2 ListView[T]) bool {
return lv.ж.Equal(*lv2.ж)
}
var (
_ jsonv2.MarshalerTo = (*ListView[bool])(nil)
_ jsonv2.UnmarshalerFrom = (*ListView[bool])(nil)
)
// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (lv ListView[T]) MarshalJSONTo(out *jsontext.Encoder) error {
return lv.ж.MarshalJSONTo(out)

View File

@@ -158,6 +158,11 @@ func (p *preference[T]) SetReadOnly(readonly bool) {
p.s.Metadata.ReadOnly = readonly
}
var (
_ jsonv2.MarshalerTo = (*preference[struct{}])(nil)
_ jsonv2.UnmarshalerFrom = (*preference[struct{}])(nil)
)
// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (p preference[T]) MarshalJSONTo(out *jsontext.Encoder) error {
return jsonv2.MarshalEncode(out, &p.s)

View File

@@ -128,6 +128,11 @@ type AppConnectorPrefs struct {
Advertise prefs.Item[bool] `json:",omitzero"`
}
var (
_ jsonv2.MarshalerTo = (*Prefs)(nil)
_ jsonv2.UnmarshalerFrom = (*Prefs)(nil)
)
// MarshalJSONTo implements [jsonv2.MarshalerTo].
// It is implemented as a performance improvement and to enable omission of
// unconfigured preferences from the JSON output. See the [Prefs] doc for details.

View File

@@ -19,6 +19,20 @@ import (
//go:generate go run tailscale.com/cmd/viewer --tags=test --type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup
var (
_ jsonv2.MarshalerTo = (*ItemView[*TestBundle, TestBundleView])(nil)
_ jsonv2.UnmarshalerFrom = (*ItemView[*TestBundle, TestBundleView])(nil)
_ jsonv2.MarshalerTo = (*MapView[string, string])(nil)
_ jsonv2.UnmarshalerFrom = (*MapView[string, string])(nil)
_ jsonv2.MarshalerTo = (*StructListView[*TestBundle, TestBundleView])(nil)
_ jsonv2.UnmarshalerFrom = (*StructListView[*TestBundle, TestBundleView])(nil)
_ jsonv2.MarshalerTo = (*StructMapView[string, *TestBundle, TestBundleView])(nil)
_ jsonv2.UnmarshalerFrom = (*StructMapView[string, *TestBundle, TestBundleView])(nil)
)
type TestPrefs struct {
Int32Item Item[int32] `json:",omitzero"`
UInt64Item Item[uint64] `json:",omitzero"`
@@ -53,6 +67,11 @@ type TestPrefs struct {
Group TestPrefsGroup `json:",omitzero"`
}
var (
_ jsonv2.MarshalerTo = (*TestPrefs)(nil)
_ jsonv2.UnmarshalerFrom = (*TestPrefs)(nil)
)
// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (p TestPrefs) MarshalJSONTo(out *jsontext.Encoder) error {
// The testPrefs type shadows the TestPrefs's method set,