Merge pull request #2738 from onionhammer/devel
Improved performance of json rendering with `$`
This commit is contained in:
commit
0ab2dc2954
1 changed files with 50 additions and 9 deletions
|
|
@ -815,7 +815,7 @@ proc `{}`*(node: JsonNode, keys: varargs[string]): JsonNode =
|
||||||
result = node
|
result = node
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if isNil(result) or result.kind!=JObject:
|
if isNil(result) or result.kind!=JObject:
|
||||||
return nil
|
return nil
|
||||||
result=result[key]
|
result=result[key]
|
||||||
|
|
||||||
proc `{}=`*(node: JsonNode, keys: varargs[string], value: JsonNode) =
|
proc `{}=`*(node: JsonNode, keys: varargs[string], value: JsonNode) =
|
||||||
|
|
@ -949,10 +949,51 @@ proc pretty*(node: JsonNode, indent = 2): string =
|
||||||
result = ""
|
result = ""
|
||||||
toPretty(result, node, indent)
|
toPretty(result, node, indent)
|
||||||
|
|
||||||
|
proc toUgly*(result: var string, node: JsonNode) =
|
||||||
|
## Converts `node` to its JSON Representation, without
|
||||||
|
## regard for human readability. Meant to improve '$' string
|
||||||
|
## conversion performance.
|
||||||
|
var comma = false
|
||||||
|
case node.kind:
|
||||||
|
of JArray:
|
||||||
|
result.add "["
|
||||||
|
for child in node.elems:
|
||||||
|
if comma: result.add ","
|
||||||
|
else: comma = true
|
||||||
|
result.toUgly child
|
||||||
|
result.add "]"
|
||||||
|
of JObject:
|
||||||
|
result.add "{"
|
||||||
|
for key, value in items(node.fields):
|
||||||
|
if comma: result.add ","
|
||||||
|
else: comma = true
|
||||||
|
result.add "\""
|
||||||
|
result.add key.escapeJson()
|
||||||
|
result.add "\":"
|
||||||
|
result.toUgly value
|
||||||
|
result.add "}"
|
||||||
|
of JString:
|
||||||
|
result.add "\""
|
||||||
|
result.add node.str.escapeJson()
|
||||||
|
result.add "\""
|
||||||
|
of JInt:
|
||||||
|
result.add($node.num)
|
||||||
|
of JFloat:
|
||||||
|
result.add($node.fnum)
|
||||||
|
of JBool:
|
||||||
|
result.add(if node.bval: "true" else: "false")
|
||||||
|
of JNull:
|
||||||
|
result.add "null"
|
||||||
|
|
||||||
|
proc toUgly*(node: JsonNode): string =
|
||||||
|
## Converts `node` to its JSON Representation on one line.
|
||||||
|
result = newStringOfCap(node.len shl 1)
|
||||||
|
toUgly(result, node)
|
||||||
|
|
||||||
proc `$`*(node: JsonNode): string =
|
proc `$`*(node: JsonNode): string =
|
||||||
## Converts `node` to its JSON Representation on one line.
|
## Converts `node` to its JSON Representation on one line.
|
||||||
result = ""
|
result = newStringOfCap(node.len shl 1)
|
||||||
toPretty(result, node, 0, false)
|
toUgly(result, node)
|
||||||
|
|
||||||
iterator items*(node: JsonNode): JsonNode =
|
iterator items*(node: JsonNode): JsonNode =
|
||||||
## Iterator for the items of `node`. `node` has to be a JArray.
|
## Iterator for the items of `node`. `node` has to be a JArray.
|
||||||
|
|
@ -1153,7 +1194,7 @@ when false:
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
#var node = parse("{ \"test\": null }")
|
#var node = parse("{ \"test\": null }")
|
||||||
#echo(node.existsKey("test56"))
|
#echo(node.existsKey("test56"))
|
||||||
|
|
||||||
var parsed = parseFile("tests/testdata/jsontest.json")
|
var parsed = parseFile("tests/testdata/jsontest.json")
|
||||||
var parsed2 = parseFile("tests/testdata/jsontest2.json")
|
var parsed2 = parseFile("tests/testdata/jsontest2.json")
|
||||||
|
|
||||||
|
|
@ -1192,17 +1233,17 @@ when isMainModule:
|
||||||
except:
|
except:
|
||||||
assert(false, "EInvalidIndex thrown for valid index")
|
assert(false, "EInvalidIndex thrown for valid index")
|
||||||
|
|
||||||
assert(testJson{"b"}.str=="asd", "Couldn't fetch a singly nested key with {}")
|
assert(testJson{"b"}.str=="asd", "Couldn't fetch a singly nested key with {}")
|
||||||
assert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil")
|
assert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil")
|
||||||
assert(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")
|
assert(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")
|
||||||
assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
||||||
assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
assert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
|
||||||
assert(testJson{"a"}==parseJson"[1, 2, 3, 4]", "Didn't return a non-JObject when there was one to be found")
|
assert(testJson{"a"}==parseJson"[1, 2, 3, 4]", "Didn't return a non-JObject when there was one to be found")
|
||||||
assert(isNil(parseJson("[1, 2, 3]"){"foo"}), "Indexing directly into a list should return nil")
|
assert(isNil(parseJson("[1, 2, 3]"){"foo"}), "Indexing directly into a list should return nil")
|
||||||
|
|
||||||
# Generator:
|
# Generator:
|
||||||
var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
|
var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
|
||||||
assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||||
|
|
||||||
var j2 = %*
|
var j2 = %*
|
||||||
[
|
[
|
||||||
|
|
@ -1230,7 +1271,7 @@ when isMainModule:
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||||
|
|
||||||
when not defined(testing):
|
when not defined(testing):
|
||||||
discard """
|
discard """
|
||||||
while true:
|
while true:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue