Skip to content

Commit 2e19790

Browse files
Maisem Alimaisem
Maisem Ali
authored andcommitted
types/views: add JSON marshal/unmarshal and AsMap to Map
This allows cloning a Map as well as marshaling the Map as JSON. Updates tailscale/corp#12754 Signed-off-by: Maisem Ali <[email protected]>
1 parent e42be5a commit 2e19790

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

cmd/derper/depaware.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
182182
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
183183
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
184184
golang.org/x/exp/constraints from golang.org/x/exp/slices
185+
golang.org/x/exp/maps from tailscale.com/types/views
185186
golang.org/x/exp/slices from tailscale.com/net/tsaddr+
186187
L golang.org/x/net/bpf from github.com/mdlayher/netlink+
187188
golang.org/x/net/dns/dnsmessage from net+

cmd/tailscale/depaware.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
173173
golang.org/x/crypto/pbkdf2 from software.sslmate.com/src/go-pkcs12
174174
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
175175
golang.org/x/exp/constraints from golang.org/x/exp/slices
176+
golang.org/x/exp/maps from tailscale.com/types/views
176177
golang.org/x/exp/slices from tailscale.com/net/tsaddr+
177178
golang.org/x/net/bpf from github.com/mdlayher/netlink+
178179
golang.org/x/net/dns/dnsmessage from net+

cmd/tailscaled/depaware.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
379379
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
380380
LD golang.org/x/crypto/ssh from tailscale.com/ssh/tailssh+
381381
golang.org/x/exp/constraints from golang.org/x/exp/slices+
382-
golang.org/x/exp/maps from tailscale.com/wgengine
382+
golang.org/x/exp/maps from tailscale.com/wgengine+
383383
golang.org/x/exp/slices from tailscale.com/ipn/ipnlocal+
384384
golang.org/x/net/bpf from github.com/mdlayher/genetlink+
385385
golang.org/x/net/dns/dnsmessage from net+

types/views/views.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import (
1010
"errors"
1111
"net/netip"
1212

13+
"golang.org/x/exp/maps"
1314
"golang.org/x/exp/slices"
1415
"tailscale.com/net/tsaddr"
1516
)
1617

17-
func unmarshalJSON[T any](b []byte, x *[]T) error {
18+
func unmarshalSliceFromJSON[T any](b []byte, x *[]T) error {
1819
if *x != nil {
1920
return errors.New("already initialized")
2021
}
@@ -64,7 +65,7 @@ type SliceView[T ViewCloner[T, V], V StructView[T]] struct {
6465
func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }
6566

6667
// UnmarshalJSON implements json.Unmarshaler.
67-
func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { return unmarshalJSON(b, &v.ж) }
68+
func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { return unmarshalSliceFromJSON(b, &v.ж) }
6869

6970
// IsNil reports whether the underlying slice is nil.
7071
func (v SliceView[T, V]) IsNil() bool { return v.ж == nil }
@@ -119,7 +120,7 @@ func (v Slice[T]) MarshalJSON() ([]byte, error) {
119120

120121
// UnmarshalJSON implements json.Unmarshaler.
121122
func (v *Slice[T]) UnmarshalJSON(b []byte) error {
122-
return unmarshalJSON(b, &v.ж)
123+
return unmarshalSliceFromJSON(b, &v.ж)
123124
}
124125

125126
// IsNil reports whether the underlying slice is nil.
@@ -332,6 +333,30 @@ func (m Map[K, V]) GetOk(k K) (V, bool) {
332333
return v, ok
333334
}
334335

336+
// MarshalJSON implements json.Marshaler.
337+
func (m Map[K, V]) MarshalJSON() ([]byte, error) {
338+
return json.Marshal(m.ж)
339+
}
340+
341+
// UnmarshalJSON implements json.Unmarshaler.
342+
// It should only be called on an uninitialized Map.
343+
func (m *Map[K, V]) UnmarshalJSON(b []byte) error {
344+
if m.ж != nil {
345+
return errors.New("already initialized")
346+
}
347+
return json.Unmarshal(b, &m.ж)
348+
}
349+
350+
// AsMap returns a shallow-clone of the underlying map.
351+
// If V is a pointer type, it is the caller's responsibility to make sure
352+
// the values are immutable.
353+
func (m *Map[K, V]) AsMap() map[K]V {
354+
if m == nil {
355+
return nil
356+
}
357+
return maps.Clone(m.ж)
358+
}
359+
335360
// MapRangeFn is the func called from a Map.Range call.
336361
// Implementations should return false to stop range.
337362
type MapRangeFn[K comparable, V any] func(k K, v V) (cont bool)

0 commit comments

Comments
 (0)