summaryrefslogtreecommitdiffhomepage
path: root/types
diff options
context:
space:
mode:
Diffstat (limited to 'types')
-rw-r--r--types/opt/value.go32
-rw-r--r--types/opt/value_jsonv1.go34
-rw-r--r--types/opt/value_jsonv2.go40
3 files changed, 74 insertions, 32 deletions
diff --git a/types/opt/value.go b/types/opt/value.go
index b47b03c81..bd90b5d90 100644
--- a/types/opt/value.go
+++ b/types/opt/value.go
@@ -6,9 +6,6 @@ package opt
import (
"fmt"
"reflect"
-
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
)
// Value is an optional value to be JSON-encoded.
@@ -99,32 +96,3 @@ func (o Value[T]) Equal(v Value[T]) bool {
}
return false
}
-
-// MarshalJSONV2 implements [jsonv2.MarshalerV2].
-func (o Value[T]) MarshalJSONV2(enc *jsontext.Encoder, opts jsonv2.Options) error {
- if !o.set {
- return enc.WriteToken(jsontext.Null)
- }
- return jsonv2.MarshalEncode(enc, &o.value, opts)
-}
-
-// UnmarshalJSONV2 implements [jsonv2.UnmarshalerV2].
-func (o *Value[T]) UnmarshalJSONV2(dec *jsontext.Decoder, opts jsonv2.Options) error {
- if dec.PeekKind() == 'n' {
- *o = Value[T]{}
- _, err := dec.ReadToken() // read null
- return err
- }
- o.set = true
- return jsonv2.UnmarshalDecode(dec, &o.value, opts)
-}
-
-// MarshalJSON implements [json.Marshaler].
-func (o Value[T]) MarshalJSON() ([]byte, error) {
- return jsonv2.Marshal(o) // uses MarshalJSONV2
-}
-
-// UnmarshalJSON implements [json.Unmarshaler].
-func (o *Value[T]) UnmarshalJSON(b []byte) error {
- return jsonv2.Unmarshal(b, o) // uses UnmarshalJSONV2
-}
diff --git a/types/opt/value_jsonv1.go b/types/opt/value_jsonv1.go
new file mode 100644
index 000000000..886d82468
--- /dev/null
+++ b/types/opt/value_jsonv1.go
@@ -0,0 +1,34 @@
+//go:build ts_omit_jsonv2
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package value
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+)
+
+var null = []byte("null")
+
+// MarshalJSON implements [json.Marshaler].
+func (o Value[T]) MarshalJSON() ([]byte, error) {
+ if !o.set {
+ return null, nil
+ }
+ return json.Marshal(o.value)
+}
+
+// UnmarshalJSON implements [json.Unmarshaler].
+func (o *Value[T]) UnmarshalJSON(b []byte) error {
+ if len(b) > 0 && b[0] == 'n' {
+ *o = Value[T]{}
+ if !bytes.Equal(b, null) {
+ return fmt.Errorf("invalid literal %q, expected %q", b, null)
+ }
+ return nil
+ }
+ return json.Unmarshal(&o.value, b)
+}
diff --git a/types/opt/value_jsonv2.go b/types/opt/value_jsonv2.go
new file mode 100644
index 000000000..e2e35865e
--- /dev/null
+++ b/types/opt/value_jsonv2.go
@@ -0,0 +1,40 @@
+//go:build !ts_omit_jsonv2
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package opt
+
+import (
+ jsonv2 "github.com/go-json-experiment/json"
+ "github.com/go-json-experiment/json/jsontext"
+)
+
+// MarshalJSON implements [json.Marshaler].
+func (o Value[T]) MarshalJSON() ([]byte, error) {
+ return jsonv2.Marshal(o) // uses MarshalJSONV2
+}
+
+// UnmarshalJSON implements [json.Unmarshaler].
+func (o *Value[T]) UnmarshalJSON(b []byte) error {
+ return jsonv2.Unmarshal(b, o) // uses UnmarshalJSONV2
+}
+
+// MarshalJSONV2 implements [jsonv2.MarshalerV2].
+func (o Value[T]) MarshalJSONV2(enc *jsontext.Encoder, opts jsonv2.Options) error {
+ if !o.set {
+ return enc.WriteToken(jsontext.Null)
+ }
+ return jsonv2.MarshalEncode(enc, &o.value, opts)
+}
+
+// UnmarshalJSONV2 implements [jsonv2.UnmarshalerV2].
+func (o *Value[T]) UnmarshalJSONV2(dec *jsontext.Decoder, opts jsonv2.Options) error {
+ if dec.PeekKind() == 'n' {
+ *o = Value[T]{}
+ _, err := dec.ReadToken() // read null
+ return err
+ }
+ o.set = true
+ return jsonv2.UnmarshalDecode(dec, &o.value, opts)
+}