Skip to content

Commit 8039a92

Browse files
committed
WIP11
Signed-off-by: Koichi Shiraishi <zchee.io@gmail.com>
1 parent 5c88785 commit 8039a92

File tree

2 files changed

+210
-0
lines changed

2 files changed

+210
-0
lines changed

generics.go

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package protocol
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// Nil represents a empty sturct that is provides nil type.
9+
type Nil struct{}
10+
11+
var (
12+
trueBytes = []byte("true")
13+
falseBytes = []byte("false")
14+
nullBytes = []byte("null")
15+
)
16+
17+
// OneOf represents a JSON-unmarshals as either a T or a U.
18+
type OneOf[T, U any] struct {
19+
// The underlying value
20+
value any
21+
}
22+
23+
var (
24+
_ Marshaler = (*OneOf[any, any])(nil)
25+
_ Unmarshaler = (*OneOf[any, any])(nil)
26+
)
27+
28+
// Any returns the underlying value.
29+
func (o *OneOf[T, U]) Any() any {
30+
if o == nil {
31+
return nil
32+
}
33+
return o.value
34+
}
35+
36+
// MarshalJSON implements [Marshaler].
37+
func (o *OneOf[T, U]) MarshalJSON() ([]byte, error) {
38+
if o == nil {
39+
return nullBytes, nil
40+
}
41+
return marshal(o.value)
42+
}
43+
44+
// UnmarshalJSON implements [Unmarshaler].
45+
func (o *OneOf[T, U]) UnmarshalJSON(data []byte) error {
46+
if bytes.Equal(data, nullBytes) {
47+
return nil
48+
}
49+
50+
// Try to unmarshal as T
51+
var valueT T
52+
errT := unmarshal(data, &valueT)
53+
if errT == nil {
54+
o.value = valueT
55+
return nil
56+
}
57+
58+
// Try to unmarshal as U
59+
var valueU U
60+
errU := unmarshal(data, &valueU)
61+
if errU == nil {
62+
o.value = valueU
63+
return nil
64+
}
65+
66+
return fmt.Errorf("cannot unmarshal to either type: %v or %v", errT, errU)
67+
}
68+
69+
// OneOf3 represents a JSON-unmarshals as either a T, U or V.
70+
type OneOf3[T, U, V any] struct {
71+
// The underlying value
72+
value any
73+
}
74+
75+
var (
76+
_ Marshaler = (*OneOf3[any, any, any])(nil)
77+
_ Unmarshaler = (*OneOf3[any, any, any])(nil)
78+
)
79+
80+
// Any returns the underlying value.
81+
func (o *OneOf3[T, U, V]) Any() any {
82+
if o == nil {
83+
return nil
84+
}
85+
return o.value
86+
}
87+
88+
// MarshalJSON implements [Marshaler].
89+
func (o *OneOf3[T, U, V]) MarshalJSON() ([]byte, error) {
90+
if o == nil {
91+
return nullBytes, nil
92+
}
93+
return marshal(o.value)
94+
}
95+
96+
// UnmarshalJSON implements [Unmarshaler].
97+
func (o *OneOf3[T, U, V]) UnmarshalJSON(data []byte) error {
98+
if bytes.Equal(data, nullBytes) {
99+
return nil
100+
}
101+
102+
// Try to unmarshal as T
103+
var valueT T
104+
errT := unmarshal(data, &valueT)
105+
if errT == nil {
106+
o.value = valueT
107+
return nil
108+
}
109+
110+
// Try to unmarshal as U
111+
var valueU U
112+
errU := unmarshal(data, &valueU)
113+
if errU == nil {
114+
o.value = valueU
115+
return nil
116+
}
117+
118+
// Try to unmarshal as V
119+
var valueV V
120+
errV := unmarshal(data, &valueV)
121+
if errV == nil {
122+
o.value = valueV
123+
return nil
124+
}
125+
126+
return fmt.Errorf("cannot unmarshal to either type: %v or %v or %v", errT, errU, errV)
127+
}
128+
129+
// OneOf4 represents a JSON-unmarshals as either a T, U, V or V.
130+
type OneOf4[T, U, V, Y any] struct {
131+
// The underlying value
132+
value any
133+
}
134+
135+
var (
136+
_ Marshaler = (*OneOf4[any, any, any, any])(nil)
137+
_ Unmarshaler = (*OneOf4[any, any, any, any])(nil)
138+
)
139+
140+
// Any returns the underlying value.
141+
func (o *OneOf4[T, U, V, Y]) Any() any {
142+
if o == nil {
143+
return nil
144+
}
145+
return o.value
146+
}
147+
148+
// MarshalJSON implements [Marshaler].
149+
func (o *OneOf4[T, U, V, Y]) MarshalJSON() ([]byte, error) {
150+
if o == nil {
151+
return nullBytes, nil
152+
}
153+
return marshal(o.value)
154+
}
155+
156+
// UnmarshalJSON implements [Unmarshaler].
157+
func (o *OneOf4[T, U, V, Y]) UnmarshalJSON(data []byte) error {
158+
if bytes.Equal(data, nullBytes) {
159+
return nil
160+
}
161+
162+
// Try to unmarshal as T
163+
var valueT T
164+
errT := unmarshal(data, &valueT)
165+
if errT == nil {
166+
o.value = valueT
167+
return nil
168+
}
169+
170+
// Try to unmarshal as U
171+
var valueU U
172+
errU := unmarshal(data, &valueU)
173+
if errU == nil {
174+
o.value = valueU
175+
return nil
176+
}
177+
178+
// Try to unmarshal as V
179+
var valueV V
180+
errV := unmarshal(data, &valueV)
181+
if errV == nil {
182+
o.value = valueV
183+
return nil
184+
}
185+
186+
// Try to unmarshal as V
187+
var valueY Y
188+
errY := unmarshal(data, &valueY)
189+
if errY == nil {
190+
o.value = valueV
191+
return nil
192+
}
193+
194+
return fmt.Errorf("cannot unmarshal to either type: %v or %v or %v or %v", errT, errU, errV, errY)
195+
}

protocol.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ import (
1313
"go.lsp.dev/jsonrpc2"
1414
)
1515

16+
// Marshaler is the interface implemented by types that
17+
// can marshal themselves into valid JSON.
18+
type Marshaler interface {
19+
MarshalJSON() ([]byte, error)
20+
}
21+
1622
// MarshalFunc function type of marshal JSON data.
1723
//
1824
// Default is used [json.Marshal].
@@ -24,6 +30,15 @@ func RegiserMarshaler(fn MarshalFunc) {
2430
marshal = fn
2531
}
2632

33+
// Unmarshaler is the interface implemented by types
34+
// that can unmarshal a JSON description of themselves.
35+
// The input can be assumed to be a valid encoding of
36+
// a JSON value. UnmarshalJSON must copy the JSON data
37+
// if it wishes to retain the data after returning.
38+
type Unmarshaler interface {
39+
UnmarshalJSON([]byte) error
40+
}
41+
2742
// UnmarshalFunc function type of unmarshal JSON data.
2843
//
2944
// Default is used [json.Unmarshal].

0 commit comments

Comments
 (0)