...
1
2
3
4
5 package json_test
6
7 import (
8 "fmt"
9 "log"
10 "reflect"
11
12 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json"
13 )
14
15
16
17
18
19
20
21
22 type OrderedObject[V any] []ObjectMember[V]
23
24
25 type ObjectMember[V any] struct {
26 Name string
27 Value V
28 }
29
30
31 func (obj *OrderedObject[V]) MarshalNextJSON(opts json.MarshalOptions, enc *json.Encoder) error {
32 if err := enc.WriteToken(json.ObjectStart); err != nil {
33 return err
34 }
35 for i := range *obj {
36 member := &(*obj)[i]
37 if err := opts.MarshalNext(enc, &member.Name); err != nil {
38 return err
39 }
40 if err := opts.MarshalNext(enc, &member.Value); err != nil {
41 return err
42 }
43 }
44 if err := enc.WriteToken(json.ObjectEnd); err != nil {
45 return err
46 }
47 return nil
48 }
49
50
51 func (obj *OrderedObject[V]) UnmarshalNextJSON(opts json.UnmarshalOptions, dec *json.Decoder) error {
52 if k := dec.PeekKind(); k != '{' {
53 return fmt.Errorf("expected object start, but encountered %v", k)
54 }
55 if _, err := dec.ReadToken(); err != nil {
56 return err
57 }
58 for dec.PeekKind() != '}' {
59 *obj = append(*obj, ObjectMember[V]{})
60 member := &(*obj)[len(*obj)-1]
61 if err := opts.UnmarshalNext(dec, &member.Name); err != nil {
62 return err
63 }
64 if err := opts.UnmarshalNext(dec, &member.Value); err != nil {
65 return err
66 }
67 }
68 if _, err := dec.ReadToken(); err != nil {
69 return err
70 }
71 return nil
72 }
73
74
75
76 func Example_orderedObject() {
77
78
79 want := OrderedObject[string]{
80 {"fizz", "buzz"},
81 {"hello", "world"},
82 {"fizz", "wuzz"},
83 }
84 b, err := json.MarshalOptions{}.Marshal(json.EncodeOptions{
85 AllowDuplicateNames: true,
86 }, &want)
87 if err != nil {
88 log.Fatal(err)
89 }
90 var got OrderedObject[string]
91 err = json.UnmarshalOptions{}.Unmarshal(json.DecodeOptions{
92 AllowDuplicateNames: true,
93 }, b, &got)
94 if err != nil {
95 log.Fatal(err)
96 }
97
98
99 if !reflect.DeepEqual(got, want) {
100 log.Fatalf("roundtrip mismatch: got %v, want %v", got, want)
101 }
102
103
104 (*json.RawValue)(&b).Indent("", "\t")
105 fmt.Println(string(b))
106
107
108
109
110
111
112
113 }
114
View as plain text