@@ -2,16 +2,18 @@ module decoder2
2
2
3
3
import time
4
4
5
+ // Node represents a node in a JSON decoder tree.
5
6
struct Node {
6
- key_pos int
7
- key_len int
8
- children ? []Node
7
+ key_pos int // The position of the key in the JSON string.
8
+ key_len int // The length of the key in the JSON string.
9
+ children ? []Node // The children nodes of the current node.
9
10
}
10
11
12
+ // Decoder represents a JSON decoder.
11
13
struct Decoder {
12
- json_data string
14
+ json string // json is the JSON data to be decoded.
13
15
mut :
14
- idx int
16
+ idx int // idx is the current index of the decoder.
15
17
}
16
18
17
19
pub enum ValueKind {
@@ -37,7 +39,7 @@ pub fn decode[T](val string) !T {
37
39
mut nodes := []Node{}
38
40
39
41
mut decoder := Decoder{
40
- json_data : val
42
+ json : val
41
43
}
42
44
43
45
// TODO needs performance improvements
@@ -96,30 +98,30 @@ fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val
96
98
start := (node.key_pos + node.key_len) + 3
97
99
mut end := start
98
100
for {
99
- if decoder.json_data [end] == `,` || decoder.json_data [end] == `}` {
101
+ if decoder.json [end] == `,` || decoder.json [end] == `}` {
100
102
break
101
103
}
102
104
103
105
end++
104
106
}
105
- mut value_kind := get_value_kind (decoder.json_data [start])
107
+ mut value_kind := get_value_kind (decoder.json [start])
106
108
107
109
$if T is string {
108
110
if value_kind == .string_ {
109
- return decoder.json_data [start + 1 ..end - 1 ]
111
+ return decoder.json [start + 1 ..end - 1 ]
110
112
} else if value_kind == .object {
111
113
} else if value_kind == .array {
112
114
} else {
113
- return decoder.json_data [start..end]
115
+ return decoder.json [start..end]
114
116
}
115
117
return ''
116
118
} $else $if T is $int {
117
119
if value_kind == .string_ {
118
- return decoder.json_data [start + 1 ..end - 1 ].int ()
120
+ return decoder.json [start + 1 ..end - 1 ].int ()
119
121
} else if value_kind == .object {
120
122
} else if value_kind == .array {
121
123
} else {
122
- return decoder.json_data [start..end].int ()
124
+ return decoder.json [start..end].int ()
123
125
}
124
126
}
125
127
return T{}
@@ -132,36 +134,37 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
132
134
mut node := nodes[i]
133
135
134
136
if node.key_len == field.name.len {
137
+ // This `vmemcmp` compares the name of a key in a JSON with a given struct field.
135
138
if unsafe {
136
- vmemcmp (decoder.json_data .str + node.key_pos, field.name.str, field.name.len) == 0
139
+ vmemcmp (decoder.json .str + node.key_pos, field.name.str, field.name.len) == 0
137
140
} {
138
141
start := (node.key_pos + node.key_len) + 3
139
142
mut end := start
140
143
for {
141
- if decoder.json_data [end] == `,` || decoder.json_data [end] == `}` {
144
+ if decoder.json [end] == `,` || decoder.json [end] == `}` {
142
145
break
143
146
}
144
147
145
148
end++
146
149
}
147
150
148
- mut value_kind := get_value_kind (decoder.json_data [start])
151
+ mut value_kind := get_value_kind (decoder.json [start])
149
152
$if field.indirections != 0 {
150
153
// REVIEW Needs clone?
151
154
$if field.indirections == 1 {
152
155
// TODO
153
156
// unsafe {
154
- // value.$(field.name) = &(decoder.json_data [start + 1..end - 1])
157
+ // value.$(field.name) = &(decoder.json [start + 1..end - 1])
155
158
// }
156
159
} $else $if field.indirections == 2 {
157
160
// TODO
158
161
// unsafe {
159
- // value.$(field.name) = &&(decoder.json_data [start + 1..end - 1])
162
+ // value.$(field.name) = &&(decoder.json [start + 1..end - 1])
160
163
// }
161
164
} $else $if field.indirections == 3 {
162
165
// TODO
163
166
// unsafe {
164
- // value.$(field.name) = &&&(decoder.json_data [start + 1..end - 1])
167
+ // value.$(field.name) = &&&(decoder.json [start + 1..end - 1])
165
168
// }
166
169
}
167
170
} $else $if field.typ is $option {
@@ -176,48 +179,48 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
176
179
$for v in workaround.variants {
177
180
$if v.typ is string {
178
181
if value_kind == .string_ {
179
- // value.$(field.name) = decoder.json_data [start + 1..end - 1]
182
+ // value.$(field.name) = decoder.json [start + 1..end - 1]
180
183
} else {
181
- // value.$(field.name) = decoder.json_data [start..end]
184
+ // value.$(field.name) = decoder.json [start..end]
182
185
}
183
186
} $else $if v.typ in [$int , $float] {
184
187
$if v.typ is u32 {
185
- value.$(field.name) = decoder.json_data [start..end].u32 ()
188
+ value.$(field.name) = decoder.json [start..end].u32 ()
186
189
} $else $if v.typ is u32 {
187
190
}
188
191
189
192
$if v.typ is i8 {
190
- value.$(field.name) = decoder.json_data [start..end].i8 ()
193
+ value.$(field.name) = decoder.json [start..end].i8 ()
191
194
} $else $if v.typ is i16 {
192
- value.$(field.name) = decoder.json_data [start..end].i16 ()
195
+ value.$(field.name) = decoder.json [start..end].i16 ()
193
196
} $else $if v.typ is i32 {
194
- value.$(field.name) = decoder.json_data [start..end].i32 ()
197
+ value.$(field.name) = decoder.json [start..end].i32 ()
195
198
} $else $if v.typ is int {
196
- value.$(field.name) = decoder.json_data [start..end].int ()
199
+ value.$(field.name) = decoder.json [start..end].int ()
197
200
} $else $if v.typ is i64 {
198
- value.$(field.name) = decoder.json_data [start..end].i64 ()
201
+ value.$(field.name) = decoder.json [start..end].i64 ()
199
202
} $else $if v.typ is u8 {
200
- value.$(field.name) = decoder.json_data [start..end].u8 ()
203
+ value.$(field.name) = decoder.json [start..end].u8 ()
201
204
} $else $if v.typ is u16 {
202
- value.$(field.name) = decoder.json_data [start..end].u16 ()
205
+ value.$(field.name) = decoder.json [start..end].u16 ()
203
206
} $else $if v.typ is u32 {
204
- value.$(field.name) = decoder.json_data [start..end].u32 ()
207
+ value.$(field.name) = decoder.json [start..end].u32 ()
205
208
} $else $if v.typ is u64 {
206
- value.$(field.name) = decoder.json_data [start..end].u64 ()
209
+ value.$(field.name) = decoder.json [start..end].u64 ()
207
210
} $else $if v.typ is f32 {
208
- value.$(field.name) = decoder.json_data [start..end].f32 ()
211
+ value.$(field.name) = decoder.json [start..end].f32 ()
209
212
} $else $if v.typ is f64 {
210
- value.$(field.name) = decoder.json_data [start..end].f64 ()
213
+ value.$(field.name) = decoder.json [start..end].f64 ()
211
214
}
212
215
} $else $if v.typ is bool {
213
- if decoder.json_data [start] == `t` {
216
+ if decoder.json [start] == `t` {
214
217
value.$(field.name) = true
215
- } else if decoder.json_data [start] == `f` {
218
+ } else if decoder.json [start] == `f` {
216
219
value.$(field.name) = false
217
220
}
218
221
} $else $if v.typ is time.Time {
219
222
if value_kind == .string_ {
220
- value.$(field.name) = time.parse (decoder.json_data [start + 1 ..end - 1 ]) or {
223
+ value.$(field.name) = time.parse (decoder.json [start + 1 ..end - 1 ]) or {
221
224
time.Time{}
222
225
}
223
226
}
@@ -242,56 +245,56 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
242
245
}
243
246
}
244
247
if value_kind == .string_ {
245
- // value.$(field.name) = decoder.json_data [start + 1..end - 1]
246
- } else if decoder.json_data [start] == `t` {
248
+ // value.$(field.name) = decoder.json [start + 1..end - 1]
249
+ } else if decoder.json [start] == `t` {
247
250
value.$(field.name) = true
248
- } else if decoder.json_data [start] == `f` {
251
+ } else if decoder.json [start] == `f` {
249
252
value.$(field.name) = false
250
253
} else if value_kind == .object {
251
254
} else if value_kind == .array {
252
255
} else if value_kind == .number {
253
- // value.$(field.name) = decoder.json_data [start..end].int()
256
+ // value.$(field.name) = decoder.json [start..end].int()
254
257
} else {
255
258
}
256
259
} $else $if field.typ is string {
257
260
if value_kind == .string_ {
258
- value.$(field.name) = decoder.json_data [start + 1 ..end - 1 ]
261
+ value.$(field.name) = decoder.json [start + 1 ..end - 1 ]
259
262
} else {
260
- value.$(field.name) = decoder.json_data [start..end]
263
+ value.$(field.name) = decoder.json [start..end]
261
264
}
262
265
} $else $if field.typ in [$int , $float] {
263
266
$if field.typ is i8 {
264
- value.$(field.name) = decoder.json_data [start..end].i8 ()
267
+ value.$(field.name) = decoder.json [start..end].i8 ()
265
268
} $else $if field.typ is i16 {
266
- value.$(field.name) = decoder.json_data [start..end].i16 ()
269
+ value.$(field.name) = decoder.json [start..end].i16 ()
267
270
} $else $if field.typ is i32 {
268
- value.$(field.name) = decoder.json_data [start..end].i32 ()
271
+ value.$(field.name) = decoder.json [start..end].i32 ()
269
272
} $else $if field.typ is int {
270
- value.$(field.name) = decoder.json_data [start..end].int ()
273
+ value.$(field.name) = decoder.json [start..end].int ()
271
274
} $else $if field.typ is i64 {
272
- value.$(field.name) = decoder.json_data [start..end].i64 ()
275
+ value.$(field.name) = decoder.json [start..end].i64 ()
273
276
} $else $if field.typ is u8 {
274
- value.$(field.name) = decoder.json_data [start..end].u8 ()
277
+ value.$(field.name) = decoder.json [start..end].u8 ()
275
278
} $else $if field.typ is u16 {
276
- value.$(field.name) = decoder.json_data [start..end].u16 ()
279
+ value.$(field.name) = decoder.json [start..end].u16 ()
277
280
} $else $if field.typ is u32 {
278
- value.$(field.name) = decoder.json_data [start..end].u32 ()
281
+ value.$(field.name) = decoder.json [start..end].u32 ()
279
282
} $else $if field.typ is u64 {
280
- value.$(field.name) = decoder.json_data [start..end].u64 ()
283
+ value.$(field.name) = decoder.json [start..end].u64 ()
281
284
} $else $if field.typ is f32 {
282
- value.$(field.name) = decoder.json_data [start..end].f32 ()
285
+ value.$(field.name) = decoder.json [start..end].f32 ()
283
286
} $else $if field.typ is f64 {
284
- value.$(field.name) = decoder.json_data [start..end].f64 ()
287
+ value.$(field.name) = decoder.json [start..end].f64 ()
285
288
}
286
289
} $else $if field.typ is bool {
287
- if decoder.json_data [start] == `t` {
290
+ if decoder.json [start] == `t` {
288
291
value.$(field.name) = true
289
- } else if decoder.json_data [start] == `f` {
292
+ } else if decoder.json [start] == `f` {
290
293
value.$(field.name) = false
291
294
}
292
295
} $else $if field.typ is time.Time {
293
296
if value_kind == .string_ {
294
- value.$(field.name) = time.parse_rfc3339 (decoder.json_data [start + 1 ..end - 1 ]) or {
297
+ value.$(field.name) = time.parse_rfc3339 (decoder.json [start + 1 ..end - 1 ]) or {
295
298
time.Time{}
296
299
}
297
300
}
@@ -313,37 +316,37 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
313
316
}
314
317
}
315
318
} $else $if field.typ is $enum {
316
- value.$(field.name) = decoder.json_data [start..end].int ()
319
+ value.$(field.name) = decoder.json [start..end].int ()
317
320
} $else $if field.typ is $alias {
318
321
$if field.unaliased_typ is string {
319
322
if value_kind == .string_ {
320
- value.$(field.name) = decoder.json_data [start + 1 ..end - 1 ]
323
+ value.$(field.name) = decoder.json [start + 1 ..end - 1 ]
321
324
}
322
325
} $else $if field.unaliased_typ is time.Time {
323
326
} $else $if field.unaliased_typ is bool {
324
327
} $else $if field.unaliased_typ in [$float, $int ] {
325
328
$if field.unaliased_typ is i8 {
326
- value.$(field.name) = decoder.json_data [start..end].i8 ()
329
+ value.$(field.name) = decoder.json [start..end].i8 ()
327
330
} $else $if field.unaliased_typ is i16 {
328
- value.$(field.name) = decoder.json_data [start..end].i16 ()
331
+ value.$(field.name) = decoder.json [start..end].i16 ()
329
332
} $else $if field.unaliased_typ is i32 {
330
- value.$(field.name) = decoder.json_data [start..end].i32 ()
333
+ value.$(field.name) = decoder.json [start..end].i32 ()
331
334
} $else $if field.unaliased_typ is int {
332
- value.$(field.name) = decoder.json_data [start..end].int ()
335
+ value.$(field.name) = decoder.json [start..end].int ()
333
336
} $else $if field.unaliased_typ is i64 {
334
- value.$(field.name) = decoder.json_data [start..end].i64 ()
337
+ value.$(field.name) = decoder.json [start..end].i64 ()
335
338
} $else $if field.unaliased_typ is u8 {
336
- value.$(field.name) = decoder.json_data [start..end].u8 ()
339
+ value.$(field.name) = decoder.json [start..end].u8 ()
337
340
} $else $if field.unaliased_typ is u16 {
338
- value.$(field.name) = decoder.json_data [start..end].u16 ()
341
+ value.$(field.name) = decoder.json [start..end].u16 ()
339
342
} $else $if field.unaliased_typ is u32 {
340
- value.$(field.name) = decoder.json_data [start..end].u32 ()
343
+ value.$(field.name) = decoder.json [start..end].u32 ()
341
344
} $else $if field.unaliased_typ is u64 {
342
- value.$(field.name) = decoder.json_data [start..end].u64 ()
345
+ value.$(field.name) = decoder.json [start..end].u64 ()
343
346
} $else $if field.unaliased_typ is f32 {
344
- value.$(field.name) = decoder.json_data [start..end].f32 ()
347
+ value.$(field.name) = decoder.json [start..end].f32 ()
345
348
} $else $if field.unaliased_typ is f64 {
346
- value.$(field.name) = decoder.json_data [start..end].f64 ()
349
+ value.$(field.name) = decoder.json [start..end].f64 ()
347
350
}
348
351
} $else $if field.unaliased_typ is $array {
349
352
// TODO
@@ -375,20 +378,19 @@ fn (mut decoder Decoder) decode_map[T](nodes []Node, mut val T) {
375
378
mut end := start
376
379
377
380
for {
378
- if decoder.json_data [end] == `,` || decoder.json_data [end] == `}` {
381
+ if decoder.json [end] == `,` || decoder.json [end] == `}` {
379
382
break
380
383
}
381
384
382
385
end++
383
386
}
384
387
385
- mut value_kind := get_value_kind (decoder.json_data [start])
388
+ mut value_kind := get_value_kind (decoder.json [start])
386
389
387
390
if value_kind == .string_ {
388
- val[decoder.json_data[node.key_pos..node.key_pos + node.key_len]] = decoder.json_data[
389
- start + 1 ..end - 1 ]
391
+ val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start + 1 ..end - 1 ]
390
392
} else {
391
- val[decoder.json_data [node.key_pos..node.key_pos + node.key_len]] = decoder.json_data [start..end]
393
+ val[decoder.json [node.key_pos..node.key_pos + node.key_len]] = decoder.json [start..end]
392
394
}
393
395
}
394
396
}
@@ -399,15 +401,14 @@ fn (mut decoder Decoder) fulfill_nodes(mut nodes []Node) {
399
401
mut inside_key := false
400
402
401
403
mut actual_key_len := 0
402
- for decoder.idx < decoder.json_data .len {
403
- letter := decoder.json_data [decoder.idx]
404
+ for decoder.idx < decoder.json .len {
405
+ letter := decoder.json [decoder.idx]
404
406
if letter == ` ` && ! inside_string {
405
407
} else if letter == `\" ` {
406
- if decoder.json_data[decoder.idx - 1 ] == `{`
407
- || decoder.json_data[decoder.idx - 2 ] == `,` {
408
+ if decoder.json[decoder.idx - 1 ] == `{` || decoder.json[decoder.idx - 2 ] == `,` {
408
409
inside_key = true
409
- } else if decoder.json_data [decoder.idx + 1 ] == `:` {
410
- if decoder.json_data [decoder.idx + 3 ] == `{` {
410
+ } else if decoder.json [decoder.idx + 1 ] == `:` {
411
+ if decoder.json [decoder.idx + 3 ] == `{` {
411
412
mut children := []Node{}
412
413
key_pos := decoder.idx - actual_key_len
413
414
key_len := actual_key_len
0 commit comments