Skip to content

Commit cd02b16

Browse files
authored
Merge pull request #61 from treeform/dev
add RawJson
2 parents 981f868 + 5736b35 commit cd02b16

20 files changed

+171
-109
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,31 @@ type Entry = object
298298
}
299299
}""".fromJson(Entry)
300300
```
301+
302+
## Full support for raw-json.
303+
304+
Sometimes you don't need to parse the json, but just send it or store it in the database. You can speed this up by using `RawJson` type. What it does is prevents full parsing of that json tree and instead returns it is a `RawJson` (`disticnt string`) type. You can then do anything you want with that. Store it in a database or pass it along to some other API. Or maybe parse it later again with jsony.
305+
306+
```nim
307+
import jsony
308+
type
309+
Message = object
310+
id: uint64
311+
data: RawJson
312+
313+
let
314+
messageData = """{"id":123,"data":{"page":"base64","arr":[1,2,3]}}"""
315+
message = messageData.fromJson(Message)
316+
317+
# make sure raw json was not parsed
318+
doAssert message.data.string == """{"page":"base64","arr":[1,2,3]}"""
319+
320+
# make sure that dumping raw json produces same result
321+
doAssert message.toJson() == messageData
322+
```
323+
324+
You can also wait to parse the json later or maybe even with different types:
325+
326+
```
327+
message.data.string.fromJson(DataPayload)
328+
```

src/jsony.nim

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import jsony/objvar, strutils, tables, sets, unicode, json, options, parseutils, typetraits
1+
import jsony/objvar, std/json, std/options, std/parseutils, std/sets,
2+
std/strutils, std/tables, std/typetraits, std/unicode
23

34
type JsonError* = object of ValueError
45

@@ -10,6 +11,7 @@ when defined(release):
1011
type
1112
SomeTable*[K, V] = Table[K, V] | OrderedTable[K, V] |
1213
TableRef[K, V] | OrderedTableRef[K, V]
14+
RawJson* = distinct string
1315

1416
proc parseHook*[T](s: string, i: var int, v: var seq[T])
1517
proc parseHook*[T: enum](s: string, i: var int, v: var T)
@@ -73,10 +75,19 @@ proc parseHook*(s: string, i: var int, v: var bool) =
7375
else:
7476
# Its faster to do char by char scan:
7577
eatSpace(s, i)
76-
if i + 3 < s.len and s[i+0] == 't' and s[i+1] == 'r' and s[i+2] == 'u' and s[i+3] == 'e':
78+
if i + 3 < s.len and
79+
s[i+0] == 't' and
80+
s[i+1] == 'r' and
81+
s[i+2] == 'u' and
82+
s[i+3] == 'e':
7783
i += 4
7884
v = true
79-
elif i + 4 < s.len and s[i+0] == 'f' and s[i+1] == 'a' and s[i+2] == 'l' and s[i+3] == 's' and s[i+4] == 'e':
85+
elif i + 4 < s.len and
86+
s[i+0] == 'f' and
87+
s[i+1] == 'a' and
88+
s[i+2] == 'l' and
89+
s[i+3] == 's' and
90+
s[i+4] == 'e':
8091
i += 5
8192
v = false
8293
else:
@@ -234,7 +245,11 @@ proc parseStringFast(s: string, i: var int, v: var string) =
234245
proc parseHook*(s: string, i: var int, v: var string) =
235246
## Parse string.
236247
eatSpace(s, i)
237-
if i + 3 < s.len and s[i+0] == 'n' and s[i+1] == 'u' and s[i+2] == 'l' and s[i+3] == 'l':
248+
if i + 3 < s.len and
249+
s[i+0] == 'n' and
250+
s[i+1] == 'u' and
251+
s[i+2] == 'l' and
252+
s[i+3] == 'l':
238253
i += 4
239254
return
240255
eatChar(s, i, '"')
@@ -284,7 +299,11 @@ proc parseHook*[T: array](s: string, i: var int, v: var T) =
284299

285300
proc parseHook*[T: not object](s: string, i: var int, v: var ref T) =
286301
eatSpace(s, i)
287-
if i + 3 < s.len and s[i+0] == 'n' and s[i+1] == 'u' and s[i+2] == 'l' and s[i+3] == 'l':
302+
if i + 3 < s.len and
303+
s[i+0] == 'n' and
304+
s[i+1] == 'u' and
305+
s[i+2] == 'l' and
306+
s[i+3] == 'l':
288307
i += 4
289308
return
290309
new(v)
@@ -406,7 +425,11 @@ proc parseHook*[T: enum](s: string, i: var int, v: var T) =
406425
proc parseHook*[T: object|ref object](s: string, i: var int, v: var T) =
407426
## Parse an object or ref object.
408427
eatSpace(s, i)
409-
if i + 3 < s.len and s[i+0] == 'n' and s[i+1] == 'u' and s[i+2] == 'l' and s[i+3] == 'l':
428+
if i + 3 < s.len and
429+
s[i+0] == 'n' and
430+
s[i+1] == 'u' and
431+
s[i+2] == 'l' and
432+
s[i+3] == 'l':
410433
i += 4
411434
return
412435
eatChar(s, i, '{')
@@ -448,7 +471,11 @@ proc parseHook*[T: object|ref object](s: string, i: var int, v: var T) =
448471
proc parseHook*[T](s: string, i: var int, v: var Option[T]) =
449472
## Parse an Option.
450473
eatSpace(s, i)
451-
if i + 3 < s.len and s[i+0] == 'n' and s[i+1] == 'u' and s[i+2] == 'l' and s[i+3] == 'l':
474+
if i + 3 < s.len and
475+
s[i+0] == 'n' and
476+
s[i+1] == 'u' and
477+
s[i+2] == 'l' and
478+
s[i+3] == 'l':
452479
i += 4
453480
return
454481
var e: T
@@ -575,7 +602,7 @@ proc dumpHook*(s: var string, v: string)
575602
proc dumpHook*(s: var string, v: char)
576603
proc dumpHook*(s: var string, v: tuple)
577604
proc dumpHook*(s: var string, v: enum)
578-
type t[T] = tuple[a:string, b:T]
605+
type t[T] = tuple[a: string, b: T]
579606
proc dumpHook*[N, T](s: var string, v: array[N, t[T]])
580607
proc dumpHook*[N, T](s: var string, v: array[N, T])
581608
proc dumpHook*[T](s: var string, v: seq[T])
@@ -842,6 +869,14 @@ proc dumpHook*(s: var string, v: JsonNode) =
842869
of JBool:
843870
s.dumpHook(v.getBool)
844871

872+
proc parseHook*(s: string, i: var int, v: var RawJson) =
873+
let oldI = i
874+
skipValue(s, i)
875+
v = s[oldI ..< i].RawJson
876+
877+
proc dumpHook*(s: var string, v: RawJson) =
878+
s.add v.string
879+
845880
proc toJson*[T](v: T): string =
846881
dumpHook(result, v)
847882
@@ -860,6 +895,5 @@ template toStaticJson*(v: untyped): static[string] =
860895
# const s = v.toJsonDynamic()
861896
# s
862897
863-
864898
when defined(release):
865899
{.pop.}

tests/all.nim

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,7 @@
22
# nim js -r .\tests\all.nim
33
# nim cpp -r .\tests\all.nim
44

5-
import test_arrays
6-
import test_char
7-
import test_enums
8-
import test_errors
9-
import test_fast_numbers
10-
import test_json_in_json
11-
import test_numbers
12-
import test_objects
13-
import test_options
14-
import test_parseHook
15-
import test_sets
16-
import test_strings
17-
import test_tables
18-
import test_tojson
19-
import test_tuples
20-
import test_refs
21-
5+
import test_arrays, test_char, test_enums, test_errors, test_fast_numbers,
6+
test_json_in_json, test_numbers, test_objects, test_options, test_parseHook,
7+
test_rawjson, test_refs, test_sets, test_strings, test_tables, test_tojson, test_tuples
228
echo "all tests pass"

tests/bench.nim

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import benchy, random, streams, macros
2-
import jsony, jason
3-
import eminim
1+
import benchy, eminim, jason, jsony, macros, random, streams
42
when defined(packedjson):
53
import packedjson, packedjson/deserialiser
64
else:

tests/bench_parts.nim

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import benchy, random, streams
2-
import jsony, jason
3-
import eminim
1+
import benchy, eminim, jason, jsony, random, streams
42
when defined(packedjson):
53
import packedjson, packedjson/deserialiser
64
else:
@@ -9,7 +7,6 @@ when not defined(gcArc):
97
import serialization
108
import json_serialization except Json, toJson
119

12-
1310
block:
1411
echo "deserialize string:"
1512
var jsonStr = "\"hello there how are you?\""

tests/bench_statics.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import jsony, jason, benchy
1+
import benchy, jason, jsony
22

33
const
44
number11 = 11
@@ -57,4 +57,4 @@ timeIt "treeform/jsony object", 100:
5757

5858
timeIt "disruptek/jason object", 100:
5959
for i in 0 .. 1000:
60-
discard thing.jason.string
60+
discard thing.jason.string

tests/fuzz.nim

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import os, strutils, random, strformat, tables, jsony
2-
1+
import jsony, os, random, strformat, strutils, tables
32

43
type
54
NodeKind = enum

tests/fuzz_strings.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import random, jsony, unicode
1+
import jsony, random, unicode
22

33
randomize()
44

tests/run_extranl_suite.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import osproc, os, strutils, sequtils
1+
import os, osproc, sequtils, strutils
22

33
# https://github.com/nst/JSONTestSuite
44
# A comprehensive test suite for RFC 8259 compliant JSON parsers

tests/run_test_jsony.nim

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# Rebuild with: nim c -d:release
22

3-
import json
4-
import os
5-
3+
import json, os
64
let fn = os.paramStr(1)
75

86
try:

0 commit comments

Comments
 (0)