mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-24 01:26:39 +00:00
cmd/viewer, types/views: implement support for json/v2 (#16852)
This adds support for having every viewer type implement jsonv2.MarshalerTo and jsonv2.UnmarshalerFrom. This provides a significant boost in performance as the json package no longer needs to validate the entirety of the JSON value outputted by MarshalJSON, nor does it need to identify the boundaries of a JSON value in order to call UnmarshalJSON. For deeply nested and recursive MarshalJSON or UnmarshalJSON calls, this can improve runtime from O(N²) to O(N). This still references "github.com/go-json-experiment/json" instead of the experimental "encoding/json/v2" package now available in Go 1.25 under goexperiment.jsonv2 so that code still builds without the experiment tag. Of note, the "github.com/go-json-experiment/json" package aliases the standard library under the right build conditions. Updates tailscale/corp#791 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
@@ -136,13 +136,13 @@ func gen(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named) {
|
|||||||
writef("if src.%s[i] == nil { dst.%s[i] = nil } else {", fname, fname)
|
writef("if src.%s[i] == nil { dst.%s[i] = nil } else {", fname, fname)
|
||||||
if codegen.ContainsPointers(ptr.Elem()) {
|
if codegen.ContainsPointers(ptr.Elem()) {
|
||||||
if _, isIface := ptr.Elem().Underlying().(*types.Interface); isIface {
|
if _, isIface := ptr.Elem().Underlying().(*types.Interface); isIface {
|
||||||
it.Import("tailscale.com/types/ptr")
|
it.Import("", "tailscale.com/types/ptr")
|
||||||
writef("\tdst.%s[i] = ptr.To((*src.%s[i]).Clone())", fname, fname)
|
writef("\tdst.%s[i] = ptr.To((*src.%s[i]).Clone())", fname, fname)
|
||||||
} else {
|
} else {
|
||||||
writef("\tdst.%s[i] = src.%s[i].Clone()", fname, fname)
|
writef("\tdst.%s[i] = src.%s[i].Clone()", fname, fname)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
it.Import("tailscale.com/types/ptr")
|
it.Import("", "tailscale.com/types/ptr")
|
||||||
writef("\tdst.%s[i] = ptr.To(*src.%s[i])", fname, fname)
|
writef("\tdst.%s[i] = ptr.To(*src.%s[i])", fname, fname)
|
||||||
}
|
}
|
||||||
writef("}")
|
writef("}")
|
||||||
@@ -165,7 +165,7 @@ func gen(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named) {
|
|||||||
writef("dst.%s = src.%s.Clone()", fname, fname)
|
writef("dst.%s = src.%s.Clone()", fname, fname)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it.Import("tailscale.com/types/ptr")
|
it.Import("", "tailscale.com/types/ptr")
|
||||||
writef("if dst.%s != nil {", fname)
|
writef("if dst.%s != nil {", fname)
|
||||||
if _, isIface := base.Underlying().(*types.Interface); isIface && hasPtrs {
|
if _, isIface := base.Underlying().(*types.Interface); isIface && hasPtrs {
|
||||||
writef("\tdst.%s = ptr.To((*src.%s).Clone())", fname, fname)
|
writef("\tdst.%s = ptr.To((*src.%s).Clone())", fname, fname)
|
||||||
@@ -197,13 +197,13 @@ func gen(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named) {
|
|||||||
writef("\t\tif v == nil { dst.%s[k] = nil } else {", fname)
|
writef("\t\tif v == nil { dst.%s[k] = nil } else {", fname)
|
||||||
if base := elem.Elem().Underlying(); codegen.ContainsPointers(base) {
|
if base := elem.Elem().Underlying(); codegen.ContainsPointers(base) {
|
||||||
if _, isIface := base.(*types.Interface); isIface {
|
if _, isIface := base.(*types.Interface); isIface {
|
||||||
it.Import("tailscale.com/types/ptr")
|
it.Import("", "tailscale.com/types/ptr")
|
||||||
writef("\t\t\tdst.%s[k] = ptr.To((*v).Clone())", fname)
|
writef("\t\t\tdst.%s[k] = ptr.To((*v).Clone())", fname)
|
||||||
} else {
|
} else {
|
||||||
writef("\t\t\tdst.%s[k] = v.Clone()", fname)
|
writef("\t\t\tdst.%s[k] = v.Clone()", fname)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
it.Import("tailscale.com/types/ptr")
|
it.Import("", "tailscale.com/types/ptr")
|
||||||
writef("\t\t\tdst.%s[k] = ptr.To(*v)", fname)
|
writef("\t\t\tdst.%s[k] = ptr.To(*v)", fname)
|
||||||
}
|
}
|
||||||
writef("}")
|
writef("}")
|
||||||
@@ -224,7 +224,7 @@ func gen(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named) {
|
|||||||
writef("\t}")
|
writef("\t}")
|
||||||
writef("}")
|
writef("}")
|
||||||
} else {
|
} else {
|
||||||
it.Import("maps")
|
it.Import("", "maps")
|
||||||
writef("\tdst.%s = maps.Clone(src.%s)", fname, fname)
|
writef("\tdst.%s = maps.Clone(src.%s)", fname, fname)
|
||||||
}
|
}
|
||||||
case *types.Interface:
|
case *types.Interface:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
|
|||||||
|
|
||||||
github.com/beorn7/perks/quantile from github.com/prometheus/client_golang/prometheus
|
github.com/beorn7/perks/quantile from github.com/prometheus/client_golang/prometheus
|
||||||
💣 github.com/cespare/xxhash/v2 from github.com/prometheus/client_golang/prometheus
|
💣 github.com/cespare/xxhash/v2 from github.com/prometheus/client_golang/prometheus
|
||||||
github.com/go-json-experiment/json from tailscale.com/types/opt
|
github.com/go-json-experiment/json from tailscale.com/types/opt+
|
||||||
github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
|
github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
|
||||||
github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
|
github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
|
||||||
github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
|
github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
"tailscale.com/types/views"
|
"tailscale.com/types/views"
|
||||||
)
|
)
|
||||||
@@ -44,8 +46,17 @@ func (v StructWithPtrsView) AsStruct() *StructWithPtrs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithPtrsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithPtrsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithPtrsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithPtrsView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithPtrsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -54,7 +65,20 @@ func (v *StructWithPtrsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithPtrs
|
var x StructWithPtrs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithPtrsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithPtrs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -108,8 +132,17 @@ func (v StructWithoutPtrsView) AsStruct() *StructWithoutPtrs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithoutPtrsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithoutPtrsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithoutPtrsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithoutPtrsView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithoutPtrsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -118,7 +151,20 @@ func (v *StructWithoutPtrsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithoutPtrs
|
var x StructWithoutPtrs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithoutPtrsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithoutPtrs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -162,8 +208,17 @@ func (v MapView) AsStruct() *Map {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v MapView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v MapView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v MapView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *MapView) UnmarshalJSON(b []byte) error {
|
func (v *MapView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -172,7 +227,20 @@ func (v *MapView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Map
|
var x Map
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *MapView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Map
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -268,8 +336,17 @@ func (v StructWithSlicesView) AsStruct() *StructWithSlices {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithSlicesView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithSlicesView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithSlicesView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithSlicesView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithSlicesView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -278,7 +355,20 @@ func (v *StructWithSlicesView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithSlices
|
var x StructWithSlices
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithSlicesView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithSlices
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -342,8 +432,17 @@ func (v StructWithEmbeddedView) AsStruct() *StructWithEmbedded {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithEmbeddedView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithEmbeddedView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithEmbeddedView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithEmbeddedView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithEmbeddedView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -352,7 +451,20 @@ func (v *StructWithEmbeddedView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithEmbedded
|
var x StructWithEmbedded
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithEmbeddedView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithEmbedded
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -398,8 +510,17 @@ func (v GenericIntStructView[T]) AsStruct() *GenericIntStruct[T] {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v GenericIntStructView[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v GenericIntStructView[T]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v GenericIntStructView[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *GenericIntStructView[T]) UnmarshalJSON(b []byte) error {
|
func (v *GenericIntStructView[T]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -408,7 +529,20 @@ func (v *GenericIntStructView[T]) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x GenericIntStruct[T]
|
var x GenericIntStruct[T]
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *GenericIntStructView[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x GenericIntStruct[T]
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -470,8 +604,17 @@ func (v GenericNoPtrsStructView[T]) AsStruct() *GenericNoPtrsStruct[T] {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v GenericNoPtrsStructView[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v GenericNoPtrsStructView[T]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v GenericNoPtrsStructView[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *GenericNoPtrsStructView[T]) UnmarshalJSON(b []byte) error {
|
func (v *GenericNoPtrsStructView[T]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -480,7 +623,20 @@ func (v *GenericNoPtrsStructView[T]) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x GenericNoPtrsStruct[T]
|
var x GenericNoPtrsStruct[T]
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *GenericNoPtrsStructView[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x GenericNoPtrsStruct[T]
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -542,8 +698,17 @@ func (v GenericCloneableStructView[T, V]) AsStruct() *GenericCloneableStruct[T,
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v GenericCloneableStructView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v GenericCloneableStructView[T, V]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v GenericCloneableStructView[T, V]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *GenericCloneableStructView[T, V]) UnmarshalJSON(b []byte) error {
|
func (v *GenericCloneableStructView[T, V]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -552,7 +717,20 @@ func (v *GenericCloneableStructView[T, V]) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x GenericCloneableStruct[T, V]
|
var x GenericCloneableStruct[T, V]
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *GenericCloneableStructView[T, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x GenericCloneableStruct[T, V]
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -617,8 +795,17 @@ func (v StructWithContainersView) AsStruct() *StructWithContainers {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithContainersView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithContainersView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithContainersView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithContainersView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithContainersView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -627,7 +814,20 @@ func (v *StructWithContainersView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithContainers
|
var x StructWithContainers
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithContainersView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithContainers
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -689,8 +889,17 @@ func (v StructWithTypeAliasFieldsView) AsStruct() *StructWithTypeAliasFields {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StructWithTypeAliasFieldsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v StructWithTypeAliasFieldsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v StructWithTypeAliasFieldsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *StructWithTypeAliasFieldsView) UnmarshalJSON(b []byte) error {
|
func (v *StructWithTypeAliasFieldsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -699,7 +908,20 @@ func (v *StructWithTypeAliasFieldsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x StructWithTypeAliasFields
|
var x StructWithTypeAliasFields
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *StructWithTypeAliasFieldsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x StructWithTypeAliasFields
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -787,10 +1009,17 @@ func (v GenericTypeAliasStructView[T, T2, V2]) AsStruct() *GenericTypeAliasStruc
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (v GenericTypeAliasStructView[T, T2, V2]) MarshalJSON() ([]byte, error) {
|
func (v GenericTypeAliasStructView[T, T2, V2]) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(v.ж)
|
return jsonv1.Marshal(v.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v GenericTypeAliasStructView[T, T2, V2]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *GenericTypeAliasStructView[T, T2, V2]) UnmarshalJSON(b []byte) error {
|
func (v *GenericTypeAliasStructView[T, T2, V2]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -799,7 +1028,20 @@ func (v *GenericTypeAliasStructView[T, T2, V2]) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x GenericTypeAliasStruct[T, T2, V2]
|
var x GenericTypeAliasStruct[T, T2, V2]
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *GenericTypeAliasStructView[T, T2, V2]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x GenericTypeAliasStruct[T, T2, V2]
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -49,8 +49,17 @@ func (v {{.ViewName}}{{.TypeParamNames}}) AsStruct() *{{.StructName}}{{.TypePara
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v {{.ViewName}}{{.TypeParamNames}}) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v {{.ViewName}}{{.TypeParamNames}}) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v {{.ViewName}}{{.TypeParamNames}}) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *{{.ViewName}}{{.TypeParamNames}}) UnmarshalJSON(b []byte) error {
|
func (v *{{.ViewName}}{{.TypeParamNames}}) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -59,10 +68,23 @@ func (v *{{.ViewName}}{{.TypeParamNames}}) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x {{.StructName}}{{.TypeParamNames}}
|
var x {{.StructName}}{{.TypeParamNames}}
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж=&x
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *{{.ViewName}}{{.TypeParamNames}}) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x {{.StructName}}{{.TypeParamNames}}
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +147,10 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, _ *
|
|||||||
if !ok || codegen.IsViewType(t) {
|
if !ok || codegen.IsViewType(t) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
it.Import("encoding/json")
|
it.Import("jsonv1", "encoding/json")
|
||||||
it.Import("errors")
|
it.Import("jsonv2", "github.com/go-json-experiment/json")
|
||||||
|
it.Import("", "github.com/go-json-experiment/json/jsontext")
|
||||||
|
it.Import("", "errors")
|
||||||
|
|
||||||
args := struct {
|
args := struct {
|
||||||
StructName string
|
StructName string
|
||||||
@@ -182,11 +206,11 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, _ *
|
|||||||
switch elem.String() {
|
switch elem.String() {
|
||||||
case "byte":
|
case "byte":
|
||||||
args.FieldType = it.QualifiedName(fieldType)
|
args.FieldType = it.QualifiedName(fieldType)
|
||||||
it.Import("tailscale.com/types/views")
|
it.Import("", "tailscale.com/types/views")
|
||||||
writeTemplate("byteSliceField")
|
writeTemplate("byteSliceField")
|
||||||
default:
|
default:
|
||||||
args.FieldType = it.QualifiedName(elem)
|
args.FieldType = it.QualifiedName(elem)
|
||||||
it.Import("tailscale.com/types/views")
|
it.Import("", "tailscale.com/types/views")
|
||||||
shallow, deep, base := requiresCloning(elem)
|
shallow, deep, base := requiresCloning(elem)
|
||||||
if deep {
|
if deep {
|
||||||
switch elem.Underlying().(type) {
|
switch elem.Underlying().(type) {
|
||||||
@@ -252,7 +276,7 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, _ *
|
|||||||
writeTemplate("unsupportedField")
|
writeTemplate("unsupportedField")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it.Import("tailscale.com/types/views")
|
it.Import("", "tailscale.com/types/views")
|
||||||
args.MapKeyType = it.QualifiedName(key)
|
args.MapKeyType = it.QualifiedName(key)
|
||||||
mElem := m.Elem()
|
mElem := m.Elem()
|
||||||
var template string
|
var template string
|
||||||
|
|||||||
@@ -20,19 +20,19 @@ func TestViewerImports(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
content string
|
content string
|
||||||
typeNames []string
|
typeNames []string
|
||||||
wantImports []string
|
wantImports [][2]string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Map",
|
name: "Map",
|
||||||
content: `type Test struct { Map map[string]int }`,
|
content: `type Test struct { Map map[string]int }`,
|
||||||
typeNames: []string{"Test"},
|
typeNames: []string{"Test"},
|
||||||
wantImports: []string{"tailscale.com/types/views"},
|
wantImports: [][2]string{{"", "tailscale.com/types/views"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Slice",
|
name: "Slice",
|
||||||
content: `type Test struct { Slice []int }`,
|
content: `type Test struct { Slice []int }`,
|
||||||
typeNames: []string{"Test"},
|
typeNames: []string{"Test"},
|
||||||
wantImports: []string{"tailscale.com/types/views"},
|
wantImports: [][2]string{{"", "tailscale.com/types/views"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@@ -68,9 +68,9 @@ func TestViewerImports(t *testing.T) {
|
|||||||
genView(&output, tracker, namedType, pkg)
|
genView(&output, tracker, namedType, pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pkgName := range tt.wantImports {
|
for _, pkg := range tt.wantImports {
|
||||||
if !tracker.Has(pkgName) {
|
if !tracker.Has(pkg[0], pkg[1]) {
|
||||||
t.Errorf("missing import %q", pkgName)
|
t.Errorf("missing import %q", pkg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
package drive
|
package drive
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/types/views"
|
"tailscale.com/types/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,8 +44,17 @@ func (v ShareView) AsStruct() *Share {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ShareView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v ShareView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ShareView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *ShareView) UnmarshalJSON(b []byte) error {
|
func (v *ShareView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -52,7 +63,20 @@ func (v *ShareView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Share
|
var x Share
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *ShareView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Share
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -33,7 +33,7 @@ require (
|
|||||||
github.com/frankban/quicktest v1.14.6
|
github.com/frankban/quicktest v1.14.6
|
||||||
github.com/fxamacker/cbor/v2 v2.7.0
|
github.com/fxamacker/cbor/v2 v2.7.0
|
||||||
github.com/gaissmai/bart v0.18.0
|
github.com/gaissmai/bart v0.18.0
|
||||||
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874
|
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced
|
||||||
github.com/go-logr/zapr v1.3.0
|
github.com/go-logr/zapr v1.3.0
|
||||||
github.com/go-ole/go-ole v1.3.0
|
github.com/go-ole/go-ole v1.3.0
|
||||||
github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737
|
github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -345,8 +345,8 @@ github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0q
|
|||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY=
|
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I=
|
||||||
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
|
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||||
|
|||||||
186
ipn/ipn_view.go
186
ipn/ipn_view.go
@@ -6,10 +6,12 @@
|
|||||||
package ipn
|
package ipn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/drive"
|
"tailscale.com/drive"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/opt"
|
"tailscale.com/types/opt"
|
||||||
@@ -48,8 +50,17 @@ func (v LoginProfileView) AsStruct() *LoginProfile {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v LoginProfileView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v LoginProfileView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v LoginProfileView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *LoginProfileView) UnmarshalJSON(b []byte) error {
|
func (v *LoginProfileView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -58,7 +69,20 @@ func (v *LoginProfileView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x LoginProfile
|
var x LoginProfile
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *LoginProfileView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x LoginProfile
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -114,8 +138,17 @@ func (v PrefsView) AsStruct() *Prefs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v PrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v PrefsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v PrefsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -124,7 +157,20 @@ func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Prefs
|
var x Prefs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *PrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Prefs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -239,8 +285,17 @@ func (v ServeConfigView) AsStruct() *ServeConfig {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ServeConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v ServeConfigView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ServeConfigView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *ServeConfigView) UnmarshalJSON(b []byte) error {
|
func (v *ServeConfigView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -249,7 +304,20 @@ func (v *ServeConfigView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x ServeConfig
|
var x ServeConfig
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *ServeConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x ServeConfig
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -323,8 +391,17 @@ func (v ServiceConfigView) AsStruct() *ServiceConfig {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ServiceConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v ServiceConfigView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ServiceConfigView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *ServiceConfigView) UnmarshalJSON(b []byte) error {
|
func (v *ServiceConfigView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -333,7 +410,20 @@ func (v *ServiceConfigView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x ServiceConfig
|
var x ServiceConfig
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *ServiceConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x ServiceConfig
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -388,8 +478,17 @@ func (v TCPPortHandlerView) AsStruct() *TCPPortHandler {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TCPPortHandlerView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TCPPortHandlerView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TCPPortHandlerView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TCPPortHandlerView) UnmarshalJSON(b []byte) error {
|
func (v *TCPPortHandlerView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -398,7 +497,20 @@ func (v *TCPPortHandlerView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TCPPortHandler
|
var x TCPPortHandler
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TCPPortHandlerView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TCPPortHandler
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -446,8 +558,17 @@ func (v HTTPHandlerView) AsStruct() *HTTPHandler {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v HTTPHandlerView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v HTTPHandlerView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v HTTPHandlerView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *HTTPHandlerView) UnmarshalJSON(b []byte) error {
|
func (v *HTTPHandlerView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -456,7 +577,20 @@ func (v *HTTPHandlerView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x HTTPHandler
|
var x HTTPHandler
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *HTTPHandlerView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x HTTPHandler
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -502,8 +636,17 @@ func (v WebServerConfigView) AsStruct() *WebServerConfig {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v WebServerConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v WebServerConfigView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v WebServerConfigView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *WebServerConfigView) UnmarshalJSON(b []byte) error {
|
func (v *WebServerConfigView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -512,7 +655,20 @@ func (v *WebServerConfigView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x WebServerConfig
|
var x WebServerConfig
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *WebServerConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x WebServerConfig
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
package tailcfg
|
package tailcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/opt"
|
"tailscale.com/types/opt"
|
||||||
@@ -49,8 +51,17 @@ func (v UserView) AsStruct() *User {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v UserView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v UserView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v UserView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *UserView) UnmarshalJSON(b []byte) error {
|
func (v *UserView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -59,7 +70,20 @@ func (v *UserView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x User
|
var x User
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *UserView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x User
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -107,8 +131,17 @@ func (v NodeView) AsStruct() *Node {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v NodeView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v NodeView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v NodeView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *NodeView) UnmarshalJSON(b []byte) error {
|
func (v *NodeView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -117,7 +150,20 @@ func (v *NodeView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Node
|
var x Node
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *NodeView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Node
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -246,8 +292,17 @@ func (v HostinfoView) AsStruct() *Hostinfo {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v HostinfoView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v HostinfoView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v HostinfoView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *HostinfoView) UnmarshalJSON(b []byte) error {
|
func (v *HostinfoView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -256,7 +311,20 @@ func (v *HostinfoView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Hostinfo
|
var x Hostinfo
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *HostinfoView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Hostinfo
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -380,8 +448,17 @@ func (v NetInfoView) AsStruct() *NetInfo {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v NetInfoView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v NetInfoView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v NetInfoView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *NetInfoView) UnmarshalJSON(b []byte) error {
|
func (v *NetInfoView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -390,7 +467,20 @@ func (v *NetInfoView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x NetInfo
|
var x NetInfo
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *NetInfoView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x NetInfo
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -460,8 +550,17 @@ func (v LoginView) AsStruct() *Login {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v LoginView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v LoginView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v LoginView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *LoginView) UnmarshalJSON(b []byte) error {
|
func (v *LoginView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -470,7 +569,20 @@ func (v *LoginView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Login
|
var x Login
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *LoginView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Login
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -521,8 +633,17 @@ func (v DNSConfigView) AsStruct() *DNSConfig {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DNSConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v DNSConfigView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v DNSConfigView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *DNSConfigView) UnmarshalJSON(b []byte) error {
|
func (v *DNSConfigView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -531,7 +652,20 @@ func (v *DNSConfigView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x DNSConfig
|
var x DNSConfig
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *DNSConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x DNSConfig
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -602,8 +736,17 @@ func (v RegisterResponseView) AsStruct() *RegisterResponse {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v RegisterResponseView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v RegisterResponseView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v RegisterResponseView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *RegisterResponseView) UnmarshalJSON(b []byte) error {
|
func (v *RegisterResponseView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -612,7 +755,20 @@ func (v *RegisterResponseView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x RegisterResponse
|
var x RegisterResponse
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *RegisterResponseView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x RegisterResponse
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -668,8 +824,17 @@ func (v RegisterResponseAuthView) AsStruct() *RegisterResponseAuth {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v RegisterResponseAuthView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v RegisterResponseAuthView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v RegisterResponseAuthView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *RegisterResponseAuthView) UnmarshalJSON(b []byte) error {
|
func (v *RegisterResponseAuthView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -678,7 +843,20 @@ func (v *RegisterResponseAuthView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x RegisterResponseAuth
|
var x RegisterResponseAuth
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *RegisterResponseAuthView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x RegisterResponseAuth
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -726,8 +904,17 @@ func (v RegisterRequestView) AsStruct() *RegisterRequest {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v RegisterRequestView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v RegisterRequestView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v RegisterRequestView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *RegisterRequestView) UnmarshalJSON(b []byte) error {
|
func (v *RegisterRequestView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -736,7 +923,20 @@ func (v *RegisterRequestView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x RegisterRequest
|
var x RegisterRequest
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *RegisterRequestView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x RegisterRequest
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -816,8 +1016,17 @@ func (v DERPHomeParamsView) AsStruct() *DERPHomeParams {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DERPHomeParamsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v DERPHomeParamsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v DERPHomeParamsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *DERPHomeParamsView) UnmarshalJSON(b []byte) error {
|
func (v *DERPHomeParamsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -826,7 +1035,20 @@ func (v *DERPHomeParamsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x DERPHomeParams
|
var x DERPHomeParams
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *DERPHomeParamsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x DERPHomeParams
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -870,8 +1092,17 @@ func (v DERPRegionView) AsStruct() *DERPRegion {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DERPRegionView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v DERPRegionView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v DERPRegionView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *DERPRegionView) UnmarshalJSON(b []byte) error {
|
func (v *DERPRegionView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -880,7 +1111,20 @@ func (v *DERPRegionView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x DERPRegion
|
var x DERPRegion
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *DERPRegionView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x DERPRegion
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -938,8 +1182,17 @@ func (v DERPMapView) AsStruct() *DERPMap {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DERPMapView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v DERPMapView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v DERPMapView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *DERPMapView) UnmarshalJSON(b []byte) error {
|
func (v *DERPMapView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -948,7 +1201,20 @@ func (v *DERPMapView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x DERPMap
|
var x DERPMap
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *DERPMapView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x DERPMap
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -999,8 +1265,17 @@ func (v DERPNodeView) AsStruct() *DERPNode {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DERPNodeView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v DERPNodeView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v DERPNodeView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *DERPNodeView) UnmarshalJSON(b []byte) error {
|
func (v *DERPNodeView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1009,7 +1284,20 @@ func (v *DERPNodeView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x DERPNode
|
var x DERPNode
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *DERPNodeView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x DERPNode
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1073,8 +1361,17 @@ func (v SSHRuleView) AsStruct() *SSHRule {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v SSHRuleView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v SSHRuleView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v SSHRuleView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *SSHRuleView) UnmarshalJSON(b []byte) error {
|
func (v *SSHRuleView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1083,7 +1380,20 @@ func (v *SSHRuleView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x SSHRule
|
var x SSHRule
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *SSHRuleView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x SSHRule
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1139,8 +1449,17 @@ func (v SSHActionView) AsStruct() *SSHAction {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v SSHActionView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v SSHActionView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v SSHActionView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *SSHActionView) UnmarshalJSON(b []byte) error {
|
func (v *SSHActionView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1149,7 +1468,20 @@ func (v *SSHActionView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x SSHAction
|
var x SSHAction
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *SSHActionView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x SSHAction
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1211,8 +1543,17 @@ func (v SSHPrincipalView) AsStruct() *SSHPrincipal {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v SSHPrincipalView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v SSHPrincipalView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v SSHPrincipalView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error {
|
func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1221,7 +1562,20 @@ func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x SSHPrincipal
|
var x SSHPrincipal
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *SSHPrincipalView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x SSHPrincipal
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1273,8 +1627,17 @@ func (v ControlDialPlanView) AsStruct() *ControlDialPlan {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ControlDialPlanView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v ControlDialPlanView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ControlDialPlanView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *ControlDialPlanView) UnmarshalJSON(b []byte) error {
|
func (v *ControlDialPlanView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1283,7 +1646,20 @@ func (v *ControlDialPlanView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x ControlDialPlan
|
var x ControlDialPlan
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *ControlDialPlanView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x ControlDialPlan
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1327,8 +1703,17 @@ func (v LocationView) AsStruct() *Location {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v LocationView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v LocationView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v LocationView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *LocationView) UnmarshalJSON(b []byte) error {
|
func (v *LocationView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1337,7 +1722,20 @@ func (v *LocationView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Location
|
var x Location
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *LocationView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Location
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1391,8 +1789,17 @@ func (v UserProfileView) AsStruct() *UserProfile {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v UserProfileView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v UserProfileView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v UserProfileView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *UserProfileView) UnmarshalJSON(b []byte) error {
|
func (v *UserProfileView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1401,7 +1808,20 @@ func (v *UserProfileView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x UserProfile
|
var x UserProfile
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *UserProfileView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x UserProfile
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -1450,8 +1870,17 @@ func (v VIPServiceView) AsStruct() *VIPService {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VIPServiceView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v VIPServiceView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v VIPServiceView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *VIPServiceView) UnmarshalJSON(b []byte) error {
|
func (v *VIPServiceView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -1460,7 +1889,20 @@ func (v *VIPServiceView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x VIPService
|
var x VIPService
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *VIPServiceView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x VIPService
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
package dnstype
|
package dnstype
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/types/views"
|
"tailscale.com/types/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,8 +45,17 @@ func (v ResolverView) AsStruct() *Resolver {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ResolverView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v ResolverView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ResolverView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *ResolverView) UnmarshalJSON(b []byte) error {
|
func (v *ResolverView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -53,7 +64,20 @@ func (v *ResolverView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Resolver
|
var x Resolver
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *ResolverView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Resolver
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
package persist
|
package persist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/structs"
|
"tailscale.com/types/structs"
|
||||||
@@ -45,8 +47,17 @@ func (v PersistView) AsStruct() *Persist {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v PersistView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v PersistView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v PersistView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *PersistView) UnmarshalJSON(b []byte) error {
|
func (v *PersistView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -55,7 +66,20 @@ func (v *PersistView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Persist
|
var x Persist
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *PersistView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Persist
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
package prefs_example
|
package prefs_example
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/drive"
|
"tailscale.com/drive"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/opt"
|
"tailscale.com/types/opt"
|
||||||
@@ -48,8 +50,17 @@ func (v PrefsView) AsStruct() *Prefs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v PrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v PrefsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v PrefsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -58,7 +69,20 @@ func (v *PrefsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x Prefs
|
var x Prefs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *PrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x Prefs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -160,8 +184,17 @@ func (v AutoUpdatePrefsView) AsStruct() *AutoUpdatePrefs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v AutoUpdatePrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v AutoUpdatePrefsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v AutoUpdatePrefsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *AutoUpdatePrefsView) UnmarshalJSON(b []byte) error {
|
func (v *AutoUpdatePrefsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -170,7 +203,20 @@ func (v *AutoUpdatePrefsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x AutoUpdatePrefs
|
var x AutoUpdatePrefs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *AutoUpdatePrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x AutoUpdatePrefs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -214,8 +260,17 @@ func (v AppConnectorPrefsView) AsStruct() *AppConnectorPrefs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v AppConnectorPrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v AppConnectorPrefsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v AppConnectorPrefsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *AppConnectorPrefsView) UnmarshalJSON(b []byte) error {
|
func (v *AppConnectorPrefsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -224,7 +279,20 @@ func (v *AppConnectorPrefsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x AppConnectorPrefs
|
var x AppConnectorPrefs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *AppConnectorPrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x AppConnectorPrefs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
package prefs
|
package prefs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup -tags=test
|
//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup -tags=test
|
||||||
@@ -41,8 +44,17 @@ func (v TestPrefsView) AsStruct() *TestPrefs {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TestPrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TestPrefsView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TestPrefsView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TestPrefsView) UnmarshalJSON(b []byte) error {
|
func (v *TestPrefsView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -51,7 +63,20 @@ func (v *TestPrefsView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TestPrefs
|
var x TestPrefs
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TestPrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TestPrefs
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -145,8 +170,17 @@ func (v TestBundleView) AsStruct() *TestBundle {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TestBundleView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TestBundleView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TestBundleView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TestBundleView) UnmarshalJSON(b []byte) error {
|
func (v *TestBundleView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -155,7 +189,20 @@ func (v *TestBundleView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TestBundle
|
var x TestBundle
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TestBundleView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TestBundle
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -200,8 +247,17 @@ func (v TestValueStructView) AsStruct() *TestValueStruct {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TestValueStructView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TestValueStructView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TestValueStructView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TestValueStructView) UnmarshalJSON(b []byte) error {
|
func (v *TestValueStructView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -210,7 +266,20 @@ func (v *TestValueStructView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TestValueStruct
|
var x TestValueStruct
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TestValueStructView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TestValueStruct
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -253,8 +322,17 @@ func (v TestGenericStructView[T]) AsStruct() *TestGenericStruct[T] {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TestGenericStructView[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TestGenericStructView[T]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TestGenericStructView[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TestGenericStructView[T]) UnmarshalJSON(b []byte) error {
|
func (v *TestGenericStructView[T]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -263,7 +341,20 @@ func (v *TestGenericStructView[T]) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TestGenericStruct[T]
|
var x TestGenericStruct[T]
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TestGenericStructView[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TestGenericStruct[T]
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
@@ -308,8 +399,17 @@ func (v TestPrefsGroupView) AsStruct() *TestPrefsGroup {
|
|||||||
return v.ж.Clone()
|
return v.ж.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TestPrefsGroupView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
|
func (v TestPrefsGroupView) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v TestPrefsGroupView) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
func (v *TestPrefsGroupView) UnmarshalJSON(b []byte) error {
|
func (v *TestPrefsGroupView) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
@@ -318,7 +418,20 @@ func (v *TestPrefsGroupView) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var x TestPrefsGroup
|
var x TestPrefsGroup
|
||||||
if err := json.Unmarshal(b, &x); err != nil {
|
if err := jsonv1.Unmarshal(b, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.ж = &x
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
func (v *TestPrefsGroupView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
var x TestPrefsGroup
|
||||||
|
if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.ж = &x
|
v.ж = &x
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package views
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
jsonv1 "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"iter"
|
"iter"
|
||||||
@@ -15,20 +15,12 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"tailscale.com/types/ptr"
|
"tailscale.com/types/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func unmarshalSliceFromJSON[T any](b []byte, x *[]T) error {
|
|
||||||
if *x != nil {
|
|
||||||
return errors.New("already initialized")
|
|
||||||
}
|
|
||||||
if len(b) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return json.Unmarshal(b, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByteSlice is a read-only accessor for types that are backed by a []byte.
|
// ByteSlice is a read-only accessor for types that are backed by a []byte.
|
||||||
type ByteSlice[T ~[]byte] struct {
|
type ByteSlice[T ~[]byte] struct {
|
||||||
// ж is the underlying mutable value, named with a hard-to-type
|
// ж is the underlying mutable value, named with a hard-to-type
|
||||||
@@ -93,15 +85,32 @@ func (v ByteSlice[T]) SliceTo(i int) ByteSlice[T] { return ByteSlice[T]{v.ж[:i]
|
|||||||
// Slice returns v[i:j]
|
// Slice returns v[i:j]
|
||||||
func (v ByteSlice[T]) Slice(i, j int) ByteSlice[T] { return ByteSlice[T]{v.ж[i:j]} }
|
func (v ByteSlice[T]) Slice(i, j int) ByteSlice[T] { return ByteSlice[T]{v.ж[i:j]} }
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (v ByteSlice[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
func (v ByteSlice[T]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v ByteSlice[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
|
// It must only be called on an uninitialized ByteSlice.
|
||||||
func (v *ByteSlice[T]) UnmarshalJSON(b []byte) error {
|
func (v *ByteSlice[T]) UnmarshalJSON(b []byte) error {
|
||||||
if v.ж != nil {
|
if v.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
return json.Unmarshal(b, &v.ж)
|
return jsonv1.Unmarshal(b, &v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It must only be called on an uninitialized ByteSlice.
|
||||||
|
func (v *ByteSlice[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &v.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructView represents the corresponding StructView of a Viewable. The concrete types are
|
// StructView represents the corresponding StructView of a Viewable. The concrete types are
|
||||||
@@ -159,11 +168,35 @@ func (v SliceView[T, V]) All() iter.Seq2[int, V] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
|
func (v SliceView[T, V]) MarshalJSON() ([]byte, error) {
|
||||||
|
return jsonv1.Marshal(v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { return unmarshalSliceFromJSON(b, &v.ж) }
|
func (v SliceView[T, V]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
|
// It must only be called on an uninitialized SliceView.
|
||||||
|
func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
} else if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return jsonv1.Unmarshal(b, &v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It must only be called on an uninitialized SliceView.
|
||||||
|
func (v *SliceView[T, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
// IsNil reports whether the underlying slice is nil.
|
// IsNil reports whether the underlying slice is nil.
|
||||||
func (v SliceView[T, V]) IsNil() bool { return v.ж == nil }
|
func (v SliceView[T, V]) IsNil() bool { return v.ж == nil }
|
||||||
@@ -252,14 +285,34 @@ func SliceOf[T any](x []T) Slice[T] {
|
|||||||
return Slice[T]{x}
|
return Slice[T]{x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (v Slice[T]) MarshalJSON() ([]byte, error) {
|
func (v Slice[T]) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(v.ж)
|
return jsonv1.Marshal(v.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (v Slice[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
|
// It must only be called on an uninitialized Slice.
|
||||||
func (v *Slice[T]) UnmarshalJSON(b []byte) error {
|
func (v *Slice[T]) UnmarshalJSON(b []byte) error {
|
||||||
return unmarshalSliceFromJSON(b, &v.ж)
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
} else if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return jsonv1.Unmarshal(b, &v.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It must only be called on an uninitialized Slice.
|
||||||
|
func (v *Slice[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if v.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &v.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNil reports whether the underlying slice is nil.
|
// IsNil reports whether the underlying slice is nil.
|
||||||
@@ -512,18 +565,32 @@ func (m MapSlice[K, V]) GetOk(k K) (Slice[V], bool) {
|
|||||||
return SliceOf(v), ok
|
return SliceOf(v), ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (m MapSlice[K, V]) MarshalJSON() ([]byte, error) {
|
func (m MapSlice[K, V]) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(m.ж)
|
return jsonv1.Marshal(m.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (m MapSlice[K, V]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, m.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
// It should only be called on an uninitialized Map.
|
// It should only be called on an uninitialized Map.
|
||||||
func (m *MapSlice[K, V]) UnmarshalJSON(b []byte) error {
|
func (m *MapSlice[K, V]) UnmarshalJSON(b []byte) error {
|
||||||
if m.ж != nil {
|
if m.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
return json.Unmarshal(b, &m.ж)
|
return jsonv1.Unmarshal(b, &m.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It should only be called on an uninitialized MapSlice.
|
||||||
|
func (m *MapSlice[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if m.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &m.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsMap returns a shallow-clone of the underlying map.
|
// AsMap returns a shallow-clone of the underlying map.
|
||||||
@@ -600,18 +667,32 @@ func (m Map[K, V]) GetOk(k K) (V, bool) {
|
|||||||
return v, ok
|
return v, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (m Map[K, V]) MarshalJSON() ([]byte, error) {
|
func (m Map[K, V]) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(m.ж)
|
return jsonv1.Marshal(m.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (m Map[K, V]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, m.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
// It should only be called on an uninitialized Map.
|
// It should only be called on an uninitialized Map.
|
||||||
func (m *Map[K, V]) UnmarshalJSON(b []byte) error {
|
func (m *Map[K, V]) UnmarshalJSON(b []byte) error {
|
||||||
if m.ж != nil {
|
if m.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
return json.Unmarshal(b, &m.ж)
|
return jsonv1.Unmarshal(b, &m.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It must only be called on an uninitialized Map.
|
||||||
|
func (m *Map[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if m.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &m.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsMap returns a shallow-clone of the underlying map.
|
// AsMap returns a shallow-clone of the underlying map.
|
||||||
@@ -809,17 +890,32 @@ func ValuePointerOf[T any](v *T) ValuePointer[T] {
|
|||||||
return ValuePointer[T]{v}
|
return ValuePointer[T]{v}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements [json.Marshaler].
|
// MarshalJSON implements [jsonv1.Marshaler].
|
||||||
func (p ValuePointer[T]) MarshalJSON() ([]byte, error) {
|
func (p ValuePointer[T]) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(p.ж)
|
return jsonv1.Marshal(p.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements [json.Unmarshaler].
|
// MarshalJSONTo implements [jsonv2.MarshalerTo].
|
||||||
|
func (p ValuePointer[T]) MarshalJSONTo(enc *jsontext.Encoder) error {
|
||||||
|
return jsonv2.MarshalEncode(enc, p.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements [jsonv1.Unmarshaler].
|
||||||
|
// It must only be called on an uninitialized ValuePointer.
|
||||||
func (p *ValuePointer[T]) UnmarshalJSON(b []byte) error {
|
func (p *ValuePointer[T]) UnmarshalJSON(b []byte) error {
|
||||||
if p.ж != nil {
|
if p.ж != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
return json.Unmarshal(b, &p.ж)
|
return jsonv1.Unmarshal(b, &p.ж)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
|
||||||
|
// It must only be called on an uninitialized ValuePointer.
|
||||||
|
func (p *ValuePointer[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||||
|
if p.ж != nil {
|
||||||
|
return errors.New("already initialized")
|
||||||
|
}
|
||||||
|
return jsonv2.UnmarshalDecode(dec, &p.ж)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainsPointers reports whether T contains any pointers,
|
// ContainsPointers reports whether T contains any pointers,
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
package views
|
package views
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
jsonv1 "encoding/json"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -15,9 +14,27 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
|
jsonv2 "github.com/go-json-experiment/json"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"tailscale.com/types/structs"
|
"tailscale.com/types/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Statically verify that each type implements the following interfaces.
|
||||||
|
var _ = []interface {
|
||||||
|
jsonv1.Marshaler
|
||||||
|
jsonv1.Unmarshaler
|
||||||
|
jsonv2.MarshalerTo
|
||||||
|
jsonv2.UnmarshalerFrom
|
||||||
|
}{
|
||||||
|
(*ByteSlice[[]byte])(nil),
|
||||||
|
(*SliceView[*testStruct, testStructView])(nil),
|
||||||
|
(*Slice[testStruct])(nil),
|
||||||
|
(*MapSlice[*testStruct, testStructView])(nil),
|
||||||
|
(*Map[*testStruct, testStructView])(nil),
|
||||||
|
(*ValuePointer[testStruct])(nil),
|
||||||
|
}
|
||||||
|
|
||||||
type viewStruct struct {
|
type viewStruct struct {
|
||||||
Int int
|
Int int
|
||||||
Addrs Slice[netip.Prefix]
|
Addrs Slice[netip.Prefix]
|
||||||
@@ -85,12 +102,14 @@ func TestViewsJSON(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
in viewStruct
|
in viewStruct
|
||||||
wantJSON string
|
wantJSONv1 string
|
||||||
|
wantJSONv2 string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
in: viewStruct{},
|
in: viewStruct{},
|
||||||
wantJSON: `{"Int":0,"Addrs":null,"Strings":null}`,
|
wantJSONv1: `{"Int":0,"Addrs":null,"Strings":null}`,
|
||||||
|
wantJSONv2: `{"Int":0,"Addrs":[],"Strings":[]}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "everything",
|
name: "everything",
|
||||||
@@ -101,30 +120,49 @@ func TestViewsJSON(t *testing.T) {
|
|||||||
StringsPtr: &ss,
|
StringsPtr: &ss,
|
||||||
Strings: ss,
|
Strings: ss,
|
||||||
},
|
},
|
||||||
wantJSON: `{"Int":1234,"Addrs":["192.168.0.0/24"],"Strings":["bar"],"AddrsPtr":["192.168.0.0/24"],"StringsPtr":["bar"]}`,
|
wantJSONv1: `{"Int":1234,"Addrs":["192.168.0.0/24"],"Strings":["bar"],"AddrsPtr":["192.168.0.0/24"],"StringsPtr":["bar"]}`,
|
||||||
|
wantJSONv2: `{"Int":1234,"Addrs":["192.168.0.0/24"],"Strings":["bar"],"AddrsPtr":["192.168.0.0/24"],"StringsPtr":["bar"]}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
encoder := json.NewEncoder(&buf)
|
|
||||||
encoder.SetIndent("", "")
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
buf.Reset()
|
cmpOpts := cmp.Options{
|
||||||
if err := encoder.Encode(&tc.in); err != nil {
|
cmp.AllowUnexported(Slice[string]{}),
|
||||||
|
cmp.AllowUnexported(Slice[netip.Prefix]{}),
|
||||||
|
cmpopts.EquateComparable(netip.Prefix{}),
|
||||||
|
}
|
||||||
|
t.Run("JSONv1", func(t *testing.T) {
|
||||||
|
gotJSON, err := jsonv1.Marshal(tc.in)
|
||||||
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
b := buf.Bytes()
|
if string(gotJSON) != tc.wantJSONv1 {
|
||||||
gotJSON := strings.TrimSpace(string(b))
|
t.Fatalf("JSON: %s; want: %s", gotJSON, tc.wantJSONv1)
|
||||||
if tc.wantJSON != gotJSON {
|
|
||||||
t.Fatalf("JSON: %v; want: %v", gotJSON, tc.wantJSON)
|
|
||||||
}
|
}
|
||||||
var got viewStruct
|
var got viewStruct
|
||||||
if err := json.Unmarshal(b, &got); err != nil {
|
if err := jsonv1.Unmarshal(gotJSON, &got); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, tc.in) {
|
if d := cmp.Diff(got, tc.in, cmpOpts); d != "" {
|
||||||
t.Fatalf("unmarshal resulted in different output: %+v; want %+v", got, tc.in)
|
t.Fatalf("unmarshal mismatch (-got +want):\n%s", d)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
t.Run("JSONv2", func(t *testing.T) {
|
||||||
|
gotJSON, err := jsonv2.Marshal(tc.in)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if string(gotJSON) != tc.wantJSONv2 {
|
||||||
|
t.Fatalf("JSON: %s; want: %s", gotJSON, tc.wantJSONv2)
|
||||||
|
}
|
||||||
|
var got viewStruct
|
||||||
|
if err := jsonv2.Unmarshal(gotJSON, &got); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if d := cmp.Diff(got, tc.in, cmpOpts, cmpopts.EquateEmpty()); d != "" {
|
||||||
|
t.Fatalf("unmarshal mismatch (-got +want):\n%s", d)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,28 +85,35 @@ func NewImportTracker(thisPkg *types.Package) *ImportTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type namePkgPath struct {
|
||||||
|
name string // optional import name
|
||||||
|
pkgPath string
|
||||||
|
}
|
||||||
|
|
||||||
// ImportTracker provides a mechanism to track and build import paths.
|
// ImportTracker provides a mechanism to track and build import paths.
|
||||||
type ImportTracker struct {
|
type ImportTracker struct {
|
||||||
thisPkg *types.Package
|
thisPkg *types.Package
|
||||||
packages map[string]bool
|
packages map[namePkgPath]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *ImportTracker) Import(pkg string) {
|
// Import imports pkgPath under an optional import name.
|
||||||
if pkg != "" && !it.packages[pkg] {
|
func (it *ImportTracker) Import(name, pkgPath string) {
|
||||||
mak.Set(&it.packages, pkg, true)
|
if pkgPath != "" && !it.packages[namePkgPath{name, pkgPath}] {
|
||||||
|
mak.Set(&it.packages, namePkgPath{name, pkgPath}, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has reports whether the specified package has been imported.
|
// Has reports whether the specified package path has been imported
|
||||||
func (it *ImportTracker) Has(pkg string) bool {
|
// under the particular import name.
|
||||||
return it.packages[pkg]
|
func (it *ImportTracker) Has(name, pkgPath string) bool {
|
||||||
|
return it.packages[namePkgPath{name, pkgPath}]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *ImportTracker) qualifier(pkg *types.Package) string {
|
func (it *ImportTracker) qualifier(pkg *types.Package) string {
|
||||||
if it.thisPkg == pkg {
|
if it.thisPkg == pkg {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
it.Import(pkg.Path())
|
it.Import("", pkg.Path())
|
||||||
// TODO(maisem): handle conflicts?
|
// TODO(maisem): handle conflicts?
|
||||||
return pkg.Name()
|
return pkg.Name()
|
||||||
}
|
}
|
||||||
@@ -128,7 +135,11 @@ func (it *ImportTracker) PackagePrefix(pkg *types.Package) string {
|
|||||||
func (it *ImportTracker) Write(w io.Writer) {
|
func (it *ImportTracker) Write(w io.Writer) {
|
||||||
fmt.Fprintf(w, "import (\n")
|
fmt.Fprintf(w, "import (\n")
|
||||||
for s := range it.packages {
|
for s := range it.packages {
|
||||||
fmt.Fprintf(w, "\t%q\n", s)
|
if s.name == "" {
|
||||||
|
fmt.Fprintf(w, "\t%q\n", s.pkgPath)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "\t%s %q\n", s.name, s.pkgPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, ")\n\n")
|
fmt.Fprintf(w, ")\n\n")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user