Skip to content

Commit b6c2aab

Browse files
authored
json2: support encoding of optional struct fields (#16521)
1 parent ba8e61e commit b6c2aab

4 files changed

Lines changed: 247 additions & 90 deletions

File tree

vlib/x/json2/encoder.v

Lines changed: 115 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,6 @@ fn (e &Encoder) encode_any(val Any, level int, mut wr io.Writer) ! {
109109
wr.write(json2.comma_bytes)!
110110
}
111111
}
112-
113-
e.encode_newline(level - 1, mut wr)!
114-
wr.write([u8(`]`)])!
115-
}
116-
[]int {
117-
wr.write([u8(`[`)])!
118-
for i in 0 .. val.len {
119-
e.encode_newline(level, mut wr)!
120-
e.encode_value_with_level(val[i], level + 1, mut wr)!
121-
if i < val.len - 1 {
122-
wr.write(json2.comma_bytes)!
123-
}
124-
}
125-
126112
e.encode_newline(level - 1, mut wr)!
127113
wr.write([u8(`]`)])!
128114
}
@@ -147,9 +133,6 @@ fn (e &Encoder) encode_value_with_level[T](val T, level int, mut wr io.Writer) !
147133
e.encode_any(val, level, mut wr)!
148134
} $else $if T is Encodable {
149135
wr.write(val.json_str().bytes())!
150-
} $else $if T is []int {
151-
// wr.write(val.str)!
152-
e.encode_any(val, level, mut wr)!
153136
} $else $if T is $Struct {
154137
e.encode_struct(val, level, mut wr)!
155138
} $else $if T is $Enum {
@@ -164,58 +147,100 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
164147
wr.write([u8(`{`)])!
165148
mut i := 0
166149
mut fields_len := 0
167-
$for _ in U.fields {
168-
fields_len++
169-
}
170150
$for field in U.fields {
171-
mut json_name := ''
172-
for attr in field.attrs {
173-
if attr.contains('json: ') {
174-
json_name = attr.replace('json: ', '')
175-
break
176-
}
177-
}
178-
e.encode_newline(level, mut wr)!
179-
if json_name != '' {
180-
e.encode_string(json_name, mut wr)!
181-
} else {
182-
e.encode_string(field.name, mut wr)!
183-
}
184-
wr.write(json2.colon_bytes)!
185-
if e.newline != 0 {
186-
wr.write(json2.space_bytes)!
151+
value := val.$(field.name)
152+
if value.str() != 'Option(error: none)' {
153+
fields_len++
187154
}
188-
if typeof(val.$(field.name)).name.contains('?') {
189-
if field.typ == 20 {
190-
if val.$(field.name).str() == 'Option(error: none)' {
191-
// TODO?
192-
} else {
193-
e.encode_string(val.$(field.name).str().replace("Option('", '').trim_string_right("')"), mut
194-
wr)!
155+
}
156+
$for field in U.fields {
157+
value := val.$(field.name)
158+
is_none := value.str() == 'Option(error: none)'
159+
if !is_none {
160+
mut json_name := ''
161+
for attr in field.attrs {
162+
if attr.contains('json: ') {
163+
json_name = attr.replace('json: ', '')
164+
break
195165
}
196166
}
197-
} else {
198-
match field.unaliased_typ {
199-
typeof[string]().idx {
200-
e.encode_string(val.$(field.name).str(), mut wr)!
201-
}
202-
typeof[int]().idx {
203-
wr.write(val.$(field.name).str().bytes())!
204-
}
205-
typeof[[]byte]().idx {
206-
//! array
207-
e.encode_array(val.$(field.name), level, mut wr)!
208-
}
209-
else {
210-
field_value := val.$(field.name)
211-
e.encode_value_with_level(field_value, level + 1, mut wr)!
167+
e.encode_newline(level, mut wr)!
168+
if json_name != '' {
169+
e.encode_string(json_name, mut wr)!
170+
} else {
171+
e.encode_string(field.name, mut wr)!
172+
}
173+
wr.write(json2.colon_bytes)!
174+
if e.newline != 0 {
175+
wr.write(json2.space_bytes)!
176+
}
177+
$if field.typ is string {
178+
e.encode_string(value.str(), mut wr)!
179+
} $else $if field.typ is bool || field.typ is f32 || field.typ is f64 || field.typ is i8
180+
|| field.typ is i16 || field.typ is int || field.typ is i64 || field.typ is u8
181+
|| field.typ is u16 || field.typ is u32 || field.typ is u64 {
182+
wr.write(value.str().bytes())!
183+
} $else $if field.typ is []string || field.typ is []bool || field.typ is []f32
184+
|| field.typ is []f64 || field.typ is []i8 || field.typ is []i16
185+
|| field.typ is []int || field.typ is []i64 || field.typ is []u8
186+
|| field.typ is []byte || field.typ is []u16 || field.typ is []u32
187+
|| field.typ is []u64 {
188+
e.encode_array(value, level, mut wr)!
189+
} $else {
190+
}
191+
$if field.typ is ?string {
192+
optional_value := val.$(field.name) as ?string
193+
e.encode_string(optional_value, mut wr)!
194+
} $else $if field.typ is ?bool {
195+
optional_value := val.$(field.name) as ?bool
196+
wr.write(Any(optional_value).str().bytes())!
197+
} $else $if field.typ is ?f32 {
198+
optional_value := val.$(field.name) as ?f32
199+
wr.write(Any(optional_value).str().bytes())!
200+
} $else $if field.typ is ?f64 {
201+
optional_value := val.$(field.name) as ?f64
202+
wr.write(Any(optional_value).str().bytes())!
203+
} $else $if field.typ is ?i8 {
204+
optional_value := val.$(field.name) as ?i8
205+
wr.write(Any(optional_value).str().bytes())!
206+
} $else $if field.typ is ?i16 {
207+
optional_value := val.$(field.name) as ?i16
208+
wr.write(Any(optional_value).str().bytes())!
209+
} $else $if field.typ is ?int {
210+
optional_value := val.$(field.name) as ?int
211+
wr.write(Any(optional_value).int().str().bytes())!
212+
} $else $if field.typ is ?[]byte {
213+
optional_value := val.$(field.name) as ?[]byte
214+
e.encode_array(optional_value, level, mut wr)!
215+
} $else $if field.typ is ?[]int {
216+
optional_value := val.$(field.name) as ?[]int
217+
e.encode_array(optional_value, level, mut wr)!
218+
} $else {
219+
if field.unaliased_typ != field.typ {
220+
match field.unaliased_typ {
221+
typeof[string]().idx {
222+
e.encode_string(value.str(), mut wr)!
223+
}
224+
typeof[bool]().idx, typeof[f32]().idx, typeof[f64]().idx, typeof[i8]().idx,
225+
typeof[i16]().idx, typeof[int]().idx, typeof[i64]().idx, typeof[u8]().idx,
226+
typeof[u16]().idx, typeof[u32]().idx, typeof[u64]().idx {
227+
wr.write(value.str().bytes())!
228+
}
229+
typeof[[]byte]().idx, typeof[[]int]().idx {
230+
e.encode_array(value, level, mut wr)!
231+
}
232+
else {
233+
// e.encode_value_with_level(value, level + 1, mut wr)!
234+
}
235+
}
212236
}
213237
}
238+
239+
if i < fields_len - 1 {
240+
wr.write(json2.comma_bytes)!
241+
}
242+
i++
214243
}
215-
if i < fields_len - 1 {
216-
wr.write(json2.comma_bytes)!
217-
}
218-
i++
219244
}
220245
e.encode_newline(level - 1, mut wr)!
221246
wr.write([u8(`}`)])!
@@ -226,7 +251,34 @@ fn (e &Encoder) encode_array[U](val U, level int, mut wr io.Writer) ! {
226251
wr.write([u8(`[`)])!
227252
for i in 0 .. val.len {
228253
e.encode_newline(level, mut wr)!
229-
e.encode_value_with_level(val[i], level + 1, mut wr)!
254+
255+
$if U is []string {
256+
e.encode_any(val[i], level + 1, mut wr)!
257+
} $else $if U is []bool {
258+
e.encode_any(bool(val[i]), level + 1, mut wr)!
259+
} $else $if U is []f32 {
260+
e.encode_any(f32(val[i]), level + 1, mut wr)!
261+
} $else $if U is []f64 {
262+
e.encode_any(f64(val[i]), level + 1, mut wr)!
263+
} $else $if U is []i8 {
264+
e.encode_any(i8(val[i]), level + 1, mut wr)!
265+
} $else $if U is []i16 {
266+
e.encode_any(i16(val[i]), level + 1, mut wr)!
267+
} $else $if U is []int {
268+
e.encode_any(int(val[i]), level + 1, mut wr)!
269+
} $else $if U is []i64 {
270+
e.encode_any(i64(val[i]), level + 1, mut wr)!
271+
} $else $if U is []u8 {
272+
e.encode_any(u8(val[i]), level + 1, mut wr)!
273+
} $else $if U is []byte {
274+
e.encode_any(u8(val[i]), level + 1, mut wr)!
275+
} $else $if U is []u16 {
276+
e.encode_any(u16(val[i]), level + 1, mut wr)!
277+
} $else $if U is []u32 {
278+
e.encode_any(u32(val[i]), level + 1, mut wr)!
279+
} $else $if U is []u64 {
280+
e.encode_any(u64(val[i]), level + 1, mut wr)!
281+
}
230282
if i < val.len - 1 {
231283
wr.write(json2.comma_bytes)!
232284
}

vlib/x/json2/json2.v

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,20 @@ pub fn encode[T](val T) string {
6464
defer {
6565
unsafe { sb.free() }
6666
}
67-
default_encoder.encode_value(val, mut sb) or {
68-
dump(err)
69-
default_encoder.encode_value[Null](null, mut sb) or {}
67+
$if T is $Array {
68+
mut array_of_any := []Any{}
69+
for value in val {
70+
array_of_any << value
71+
}
72+
default_encoder.encode_value(array_of_any, mut sb) or {
73+
dump(err)
74+
default_encoder.encode_value[Null](null, mut sb) or {}
75+
}
76+
} $else {
77+
default_encoder.encode_value(val, mut sb) or {
78+
dump(err)
79+
default_encoder.encode_value[Null](null, mut sb) or {}
80+
}
7081
}
7182
return sb.str()
7283
}

0 commit comments

Comments
 (0)