Skip to content

Commit

Permalink
Improve JSON serialisation of strtabs (nim-lang#14549)
Browse files Browse the repository at this point in the history
This creates a more compact serialisation of strtabs that is more in
line with the normal tables.
  • Loading branch information
PMunch authored Jun 5, 2020
1 parent c1ca06b commit 7cb4ef2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
35 changes: 29 additions & 6 deletions lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ runnableExamples:
doAssert $(%* Foo()) == """{"a1":0,"a2":0,"a0":0,"a3":0,"a4":0}"""

import
hashes, tables, strutils, lexbase, streams, macros, parsejson,
hashes, tables, strtabs, strutils, lexbase, streams, macros, parsejson,
options

export
Expand Down Expand Up @@ -353,6 +353,14 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} =
assert(obj.kind == JObject)
obj.fields[key] = val

proc `%`*(table: StringTableRef): JsonNode =
## Generic constructor for JSON data. Creates a new ``JObject JsonNode``.
result = newJObject()
result["mode"] = %($table.mode)
var data = newJObject()
for k, v in table: data[k] = %v
result["data"] = data

proc `%`*[T: object](o: T): JsonNode =
## Construct JsonNode from tuples and objects.
result = newJObject()
Expand Down Expand Up @@ -981,11 +989,12 @@ when defined(nimFixedForwardGeneric):
proc initFromJson[T: enum](dst: var T; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var seq[T]; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[S,T](dst: var array[S,T]; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var Table[string,T];jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var OrderedTable[string,T];jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var Table[string,T]; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var OrderedTable[string,T]; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson(dst: var StringTableRef; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var ref T; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T](dst: var Option[T]; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T: distinct](dst: var T;jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T: distinct](dst: var T; jsonNode: JsonNode; jsonPath: var string)
proc initFromJson[T: object|tuple](dst: var T; jsonNode: JsonNode; jsonPath: var string)

# initFromJson definitions
Expand Down Expand Up @@ -1043,7 +1052,7 @@ when defined(nimFixedForwardGeneric):
initFromJson(dst[i], jsonNode[i], jsonPath)
jsonPath.setLen originalJsonPathLen

proc initFromJson[T](dst: var Table[string,T];jsonNode: JsonNode; jsonPath: var string) =
proc initFromJson[T](dst: var Table[string,T]; jsonNode: JsonNode; jsonPath: var string) =
dst = initTable[string, T]()
verifyJsonKind(jsonNode, {JObject}, jsonPath)
let originalJsonPathLen = jsonPath.len
Expand All @@ -1053,7 +1062,7 @@ when defined(nimFixedForwardGeneric):
initFromJson(mgetOrPut(dst, key, default(T)), jsonNode[key], jsonPath)
jsonPath.setLen originalJsonPathLen

proc initFromJson[T](dst: var OrderedTable[string,T];jsonNode: JsonNode; jsonPath: var string) =
proc initFromJson[T](dst: var OrderedTable[string,T]; jsonNode: JsonNode; jsonPath: var string) =
dst = initOrderedTable[string,T]()
verifyJsonKind(jsonNode, {JObject}, jsonPath)
let originalJsonPathLen = jsonPath.len
Expand All @@ -1063,6 +1072,20 @@ when defined(nimFixedForwardGeneric):
initFromJson(mgetOrPut(dst, key, default(T)), jsonNode[key], jsonPath)
jsonPath.setLen originalJsonPathLen

proc mgetOrPut(tab: var StringTableRef, key: string): var string =
if not tab.hasKey(key): tab[key] = ""
result = tab[key]

proc initFromJson(dst: var StringTableRef; jsonNode: JsonNode; jsonPath: var string) =
dst = newStringTable(parseEnum[StringTableMode](jsonNode["mode"].getStr))
verifyJsonKind(jsonNode, {JObject}, jsonPath)
let originalJsonPathLen = jsonPath.len
for key in keys(jsonNode["data"].fields):
jsonPath.add '.'
jsonPath.add key
initFromJson(mgetOrPut(dst, key), jsonNode[key], jsonPath)
jsonPath.setLen originalJsonPathLen

proc initFromJson[T](dst: var ref T; jsonNode: JsonNode; jsonPath: var string) =
verifyJsonKind(jsonNode, {JObject, JNull}, jsonPath)
if jsonNode.kind == JNull:
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/strtabs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ type
StringTableObj* = object of RootObj
counter: int
data: KeyValuePairSeq
mode: StringTableMode
mode*: StringTableMode

StringTableRef* = ref StringTableObj

Expand Down

0 comments on commit 7cb4ef2

Please sign in to comment.