Skip to content

Commit 0e6fa91

Browse files
authored
abstract over reader/writer implementation (#28)
* test holo json works with holo flow master * normal load reader first, speedup already?? * fix objects * fix c and js errors * final c js fix * work around VM bug * now holoflow head
1 parent 46ece3a commit 0e6fa91

20 files changed

Lines changed: 226 additions & 206 deletions

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Not compatible with jsony's parsing/conversion behavior.
2020
# old:
2121
proc parseHook(s: string, i: var int, obj: Foo) = ...
2222
# new:
23-
proc read(format: JsonReadFormat, reader: var HoloReader, obj: Foo) = ...
23+
proc read(format: JsonReadFormat, reader: JsonReaderArg, obj: Foo) = ...
2424
```
2525

2626
This might look cluttered, but the goal is also to reduce the number of cases where a custom hook has to be written in the first place, as will be shown below.
@@ -33,12 +33,12 @@ Not compatible with jsony's parsing/conversion behavior.
3333
value: string
3434
3535
# new:
36-
proc read(format: JsonReadFormat, reader: var HoloReader, v: var seq[Header]) =
36+
proc read(format: JsonReadFormat, reader: JsonReaderArg, v: var seq[Header]) =
3737
for key in readObject[string](format, reader):
3838
var value: string
3939
read(format, reader, value)
4040
v.add(Header(key: key, value: value))
41-
proc dump(format: JsonDumpFormat, writer: var HoloWriter, v: seq[Header]) =
41+
proc dump(format: JsonDumpFormat, writer: JsonWriterArg, v: seq[Header]) =
4242
var obj: ObjectDump
4343
format.withObjectDump(writer, obj):
4444
for header in v:
@@ -120,7 +120,7 @@ Not compatible with jsony's parsing/conversion behavior.
120120
```
121121
type Foo = ref object
122122
template derefType[T](_: typedesc[ref T]): typedesc[T] = T
123-
proc startObjectRead(format: JsonReadFormat, reader: var HoloReader, foo: var derefType(Foo)) = ...
123+
proc startObjectRead(format: JsonReadFormat, reader: JsonReaderArg, foo: var derefType(Foo)) = ...
124124
```
125125

126126
This is because the `read`/`dump` hooks for objects are no longer defined for ref objects, only normal objects.

src/holo_json/dump_helpers.nim

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ./common, holo_flow/holo_writer
1+
import ./[common, dumper_common]
22

33
# don't dogfood these yet if they add to compile times:
44
type
@@ -7,38 +7,38 @@ type
77
ObjectDump* = object
88
needsComma*: bool
99

10-
proc startArrayDump*(format: JsonDumpFormat, writer: var HoloWriter): ArrayDump {.inline.} =
10+
proc startArrayDump*(format: JsonDumpFormat, writer: JsonWriterArg): ArrayDump {.inline.} =
1111
result = ArrayDump(needsComma: false)
1212
writer.write '['
1313

14-
proc finishArrayDump*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ArrayDump) {.inline.} =
14+
proc finishArrayDump*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ArrayDump) {.inline.} =
1515
writer.write ']'
1616

17-
proc startArrayItem*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ArrayDump) {.inline.} =
17+
proc startArrayItem*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ArrayDump) {.inline.} =
1818
if arr.needsComma: writer.write ','
1919
else: arr.needsComma = true
2020

21-
proc finishArrayItem*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ArrayDump) {.inline.} =
21+
proc finishArrayItem*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ArrayDump) {.inline.} =
2222
discard
2323

24-
template withArrayDump*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ArrayDump, body: typed) =
24+
template withArrayDump*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ArrayDump, body: typed) =
2525
arr = startArrayDump(format, writer)
2626
body
2727
finishArrayDump(format, writer, arr)
2828

29-
template withArrayItem*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ArrayDump, body: typed) =
29+
template withArrayItem*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ArrayDump, body: typed) =
3030
startArrayItem(format, writer, arr)
3131
body
3232
finishArrayItem(format, writer, arr)
3333

34-
proc startObjectDump*(format: JsonDumpFormat, writer: var HoloWriter): ObjectDump {.inline.} =
34+
proc startObjectDump*(format: JsonDumpFormat, writer: JsonWriterArg): ObjectDump {.inline.} =
3535
result = ObjectDump(needsComma: false)
3636
writer.write '{'
3737

38-
proc finishObjectDump*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump) {.inline.} =
38+
proc finishObjectDump*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump) {.inline.} =
3939
writer.write '}'
4040

41-
proc startObjectField*[T](format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump, name: T, raw = false) {.inline.} =
41+
proc startObjectField*[T](format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump, name: T, raw = false) {.inline.} =
4242
mixin dump
4343
if arr.needsComma: writer.write ','
4444
else: arr.needsComma = true
@@ -48,20 +48,20 @@ proc startObjectField*[T](format: JsonDumpFormat, writer: var HoloWriter, arr: v
4848
format.dump writer, name
4949
writer.write ':'
5050

51-
proc finishObjectField*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump) {.inline.} =
51+
proc finishObjectField*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump) {.inline.} =
5252
discard
5353

54-
template withObjectDump*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump, body: typed) =
54+
template withObjectDump*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump, body: typed) =
5555
arr = startObjectDump(format, writer)
5656
body
5757
finishObjectDump(format, writer, arr)
5858

59-
template withObjectField*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump, name: string, body: typed) =
59+
template withObjectField*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump, name: string, body: typed) =
6060
startObjectField(format, writer, arr, name)
6161
body
6262
finishObjectField(format, writer, arr)
6363

64-
template withRawObjectField*(format: JsonDumpFormat, writer: var HoloWriter, arr: var ObjectDump, name: string, body: typed) =
64+
template withRawObjectField*(format: JsonDumpFormat, writer: JsonWriterArg, arr: var ObjectDump, name: string, body: typed) =
6565
startObjectField(format, writer, arr, name, raw = true)
6666
body
6767
finishObjectField(format, writer, arr)

src/holo_json/dumper_basic.nim

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
## implements dumping behavior for basic types
22

3-
import ./common, holo_flow/holo_writer, std/[typetraits, unicode]
3+
import ./[common, dumper_common], std/[typetraits, unicode]
44
import std/math # for classify
55

6-
export HoloWriter, initHoloWriter, startWrite, finishWrite, write
6+
export JsonWriter, JsonWriterArg, initJsonWriter, startWrite, finishWrite, write
77

8-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: string)
8+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: string)
99
type t[T] = tuple[a: string, b: T]
10-
proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, t[T]])
11-
proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, T])
12-
proc dump*[T](format: JsonDumpFormat, writer: var HoloWriter, v: seq[T])
13-
proc dump*[T: object](format: JsonDumpFormat, writer: var HoloWriter, v: T)
14-
proc dump*[T: distinct](format: JsonDumpFormat, writer: var HoloWriter, v: T) {.inline.}
10+
proc dump*[N, T](format: JsonDumpFormat, writer: JsonWriterArg, v: array[N, t[T]])
11+
proc dump*[N, T](format: JsonDumpFormat, writer: JsonWriterArg, v: array[N, T])
12+
proc dump*[T](format: JsonDumpFormat, writer: JsonWriterArg, v: seq[T])
13+
proc dump*[T: object](format: JsonDumpFormat, writer: JsonWriterArg, v: T)
14+
proc dump*[T: distinct](format: JsonDumpFormat, writer: JsonWriterArg, v: T) {.inline.}
1515

16-
proc dump*[T: distinct](format: JsonDumpFormat, writer: var HoloWriter, v: T) {.inline.} =
16+
proc dump*[T: distinct](format: JsonDumpFormat, writer: JsonWriterArg, v: T) {.inline.} =
1717
mixin dump
1818
format.dump(writer, distinctBase(T)(v))
1919

20-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: bool) {.inline.} =
20+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: bool) {.inline.} =
2121
if v:
2222
writer.write "true"
2323
else:
@@ -32,10 +32,10 @@ const lookup = block:
3232
s.add($i)
3333
s
3434

35-
proc dumpNumberSlow(writer: var HoloWriter, v: uint|uint8|uint16|uint32|uint64) {.inline.} =
35+
proc dumpNumberSlow(writer: JsonWriterArg, v: uint|uint8|uint16|uint32|uint64) {.inline.} =
3636
writer.write $v.uint64
3737

38-
proc dumpNumberFast(writer: var HoloWriter, v: uint|uint8|uint16|uint32|uint64) =
38+
proc dumpNumberFast(writer: JsonWriterArg, v: uint|uint8|uint16|uint32|uint64) =
3939
# Its faster to not allocate a string for a number,
4040
# but to write it out the digits directly.
4141
if v == 0:
@@ -53,13 +53,13 @@ proc dumpNumberFast(writer: var HoloWriter, v: uint|uint8|uint16|uint32|uint64)
5353
digits[p] = lookup[idx*2]
5454
inc p
5555
v = v div 100
56-
var at = writer.buffer.len
56+
var at = writer.currentBuffer.len
5757
if digits[p-1] == '0':
5858
dec p
59-
writer.buffer.setLen(writer.buffer.len + p)
59+
writer.currentBuffer.setLen(writer.currentBuffer.len + p)
6060
dec p
6161
while p >= 0:
62-
writer.buffer[at] = digits[p]
62+
writer.currentBuffer[at] = digits[p]
6363
dec p
6464
inc at
6565
writer.consumeBuffer()
@@ -77,19 +77,19 @@ template uintImpl() =
7777
writer.buffer.addInt v
7878
writer.consumeBuffer()
7979

80-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: uint) {.inline.} =
80+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: uint) {.inline.} =
8181
uintImpl()
8282

83-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: uint8) {.inline.} =
83+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: uint8) {.inline.} =
8484
uintImpl()
8585

86-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: uint16) {.inline.} =
86+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: uint16) {.inline.} =
8787
uintImpl()
8888

89-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: uint32) {.inline.} =
89+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: uint32) {.inline.} =
9090
uintImpl()
9191

92-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: uint64) {.inline.} =
92+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: uint64) {.inline.} =
9393
uintImpl()
9494

9595
template intImpl() =
@@ -103,19 +103,19 @@ template intImpl() =
103103
writer.buffer.addInt v
104104
writer.consumeBuffer()
105105

106-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: int) {.inline.} =
106+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: int) {.inline.} =
107107
intImpl()
108108

109-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: int8) {.inline.} =
109+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: int8) {.inline.} =
110110
intImpl()
111111

112-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: int16) {.inline.} =
112+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: int16) {.inline.} =
113113
intImpl()
114114

115-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: int32) {.inline.} =
115+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: int32) {.inline.} =
116116
intImpl()
117117

118-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: int64) {.inline.} =
118+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: int64) {.inline.} =
119119
intImpl()
120120

121121
template floatImpl() =
@@ -141,13 +141,13 @@ template floatImpl() =
141141
# copy nim json
142142
writer.write "\"-inf\""
143143
else:
144-
writer.buffer.addFloat(v)
144+
writer.currentBuffer.addFloat(v)
145145
writer.consumeBuffer()
146146

147-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: float) =
147+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: float) =
148148
floatImpl()
149149

150-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: float32) =
150+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: float32) =
151151
floatImpl()
152152

153153
proc validRuneAt(s: string, i: int, rune: var Rune): int =
@@ -200,15 +200,15 @@ const hex = [
200200
'0', '1', '2', '3', '4', '5', '6', '7',
201201
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
202202

203-
template escapeByte(writer: var HoloWriter, c: char) =
203+
template escapeByte(writer: JsonWriterArg, c: char) =
204204
if format.useXEscape:
205205
let chars = ['\\', 'x', hex[c.int shr 4], hex[c.int and 0xF]]
206206
writer.write chars
207207
else:
208208
let chars = ['\\', 'u', '0', '0', hex[c.int shr 4], hex[c.int and 0xF]]
209209
writer.write chars
210210

211-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: string) =
211+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: string) =
212212
writer.write '"'
213213

214214
var i = 0
@@ -227,17 +227,17 @@ proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: string) =
227227
if inCopy:
228228
if i >= copyStart:
229229
let numBytes = i - copyStart
230-
let sLen = writer.buffer.len
231-
writer.buffer.setLen(sLen + numBytes)
230+
let sLen = writer.currentBuffer.len
231+
writer.currentBuffer.setLen(sLen + numBytes)
232232
when nimvm:
233233
for p in 0 ..< numBytes:
234-
writer.buffer[sLen + p] = v[copyStart + p]
234+
writer.currentBuffer[sLen + p] = v[copyStart + p]
235235
else:
236236
when not holoJsonStringCopyMem or defined(js) or defined(nimscript):
237237
for p in 0 ..< numBytes:
238-
writer.buffer[sLen + p] = v[copyStart + p]
238+
writer.currentBuffer[sLen + p] = v[copyStart + p]
239239
else:
240-
copyMem(writer.buffer[sLen].addr, v[copyStart].unsafeAddr, numBytes)
240+
copyMem(writer.currentBuffer[sLen].addr, v[copyStart].unsafeAddr, numBytes)
241241
writer.consumeBuffer()
242242
inCopy = false
243243

@@ -306,7 +306,7 @@ proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: string) =
306306

307307
writer.write '"'
308308

309-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: char) =
309+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: char) =
310310
writer.write '"'
311311
if v < 32.char or v > 127.char or v == '\\' or v == '"':
312312
case v
@@ -325,7 +325,7 @@ proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: char) =
325325
writer.write v
326326
writer.write '"'
327327

328-
proc dump*[T: tuple](format: JsonDumpFormat, writer: var HoloWriter, v: T) =
328+
proc dump*[T: tuple](format: JsonDumpFormat, writer: JsonWriterArg, v: T) =
329329
mixin dump
330330
# XXX different for named tuple?
331331
writer.write '['
@@ -336,11 +336,11 @@ proc dump*[T: tuple](format: JsonDumpFormat, writer: var HoloWriter, v: T) =
336336
format.dump(writer, e)
337337
writer.write ']'
338338

339-
template dumpStaticStr(writer: var HoloWriter, s: static string) =
339+
template dumpStaticStr(writer: JsonWriterArg, s: static string) =
340340
const s2 = holo_json.toJson(s)
341341
writer.write s2
342342

343-
proc dump*[T: enum](format: JsonDumpFormat, writer: var HoloWriter, v: T) {.inline.} =
343+
proc dump*[T: enum](format: JsonDumpFormat, writer: JsonWriterArg, v: T) {.inline.} =
344344
case format.defaultEnumOutput
345345
of EnumName:
346346
template onEnumOutput(s: string) =
@@ -357,7 +357,7 @@ proc dump*[T: enum](format: JsonDumpFormat, writer: var HoloWriter, v: T) {.inli
357357
of EnumOrd:
358358
format.dump(writer, ord(v))
359359

360-
proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, T]) =
360+
proc dump*[N, T](format: JsonDumpFormat, writer: JsonWriterArg, v: array[N, T]) =
361361
mixin dump
362362
writer.write '['
363363
var needsComma = false
@@ -367,7 +367,7 @@ proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, T])
367367
format.dump(writer, e)
368368
writer.write ']'
369369

370-
proc dump*[T](format: JsonDumpFormat, writer: var HoloWriter, v: seq[T]) =
370+
proc dump*[T](format: JsonDumpFormat, writer: JsonWriterArg, v: seq[T]) =
371371
mixin dump
372372
writer.write '['
373373
for i, e in v:
@@ -376,11 +376,11 @@ proc dump*[T](format: JsonDumpFormat, writer: var HoloWriter, v: seq[T]) =
376376
format.dump(writer, e)
377377
writer.write ']'
378378

379-
template dumpKey(writer: var HoloWriter, v: static string) =
379+
template dumpKey(writer: JsonWriterArg, v: static string) =
380380
const v2 = holo_json.toJson(v) & ":"
381381
writer.write v2
382382

383-
proc dump*[T: object](format: JsonDumpFormat, writer: var HoloWriter, v: T) =
383+
proc dump*[T: object](format: JsonDumpFormat, writer: JsonWriterArg, v: T) =
384384
mixin dump
385385
when false: # refs disabled
386386
when T is ref:
@@ -422,7 +422,7 @@ proc dump*[T: object](format: JsonDumpFormat, writer: var HoloWriter, v: T) =
422422
mapFieldOutput(v, mappings, nil, jsonDefaultOutputName, onFieldOutput)
423423
writer.write '}'
424424

425-
proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, t[T]]) =
425+
proc dump*[N, T](format: JsonDumpFormat, writer: JsonWriterArg, v: array[N, t[T]]) =
426426
mixin dump
427427
writer.write '{'
428428
var needsComma = false
@@ -435,24 +435,24 @@ proc dump*[N, T](format: JsonDumpFormat, writer: var HoloWriter, v: array[N, t[T
435435
format.dump(writer, e)
436436
writer.write '}'
437437

438-
proc dump*[T](format: JsonDumpFormat, writer: var HoloWriter, v: ref T) {.inline.} =
438+
proc dump*[T](format: JsonDumpFormat, writer: JsonWriterArg, v: ref T) {.inline.} =
439439
mixin dump
440440
if v == nil:
441441
writer.write "null"
442442
else:
443443
format.dump(writer, v[])
444444

445-
proc dump*(format: JsonDumpFormat, writer: var HoloWriter, v: RawJson) {.inline.} =
445+
proc dump*(format: JsonDumpFormat, writer: JsonWriterArg, v: RawJson) {.inline.} =
446446
writer.write v.string
447447

448448
proc dump*[T](format: JsonDumpFormat, s: var string, v: T) {.inline.} =
449449
mixin dump
450-
var writer = initHoloWriter()
450+
var writer = initJsonWriter()
451451
writer.startWrite()
452452
dump(format, writer, v)
453453
s = writer.finishWrite()
454454

455-
proc dumpJson*[T](writer: var HoloWriter, v: T) {.inline.} =
455+
proc dumpJson*[T](writer: JsonWriterArg, v: T) {.inline.} =
456456
dump(JsonDumpFormat(), writer, v)
457457

458458
proc dumpJson*[T](s: var string, v: T) {.inline.} =

src/holo_json/dumper_common.nim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import holo_flow/flush_writer
2+
export flush_writer
3+
4+
type
5+
JsonWriter* = FlushWriter
6+
JsonWriterArg* = var JsonWriter
7+
8+
proc initJsonWriter*(): JsonWriter {.inline.} =
9+
result = initFlushWriter()

0 commit comments

Comments
 (0)