json module: use ordered tables instead of ordinary tables

This commit is contained in:
Andreas Rumpf 2016-08-25 20:28:21 +02:00
commit 9b365ddfdd
2 changed files with 25 additions and 17 deletions

View file

@ -580,7 +580,7 @@ type
of JNull: of JNull:
nil nil
of JObject: of JObject:
fields*: Table[string, JsonNode] fields*: OrderedTable[string, JsonNode]
of JArray: of JArray:
elems*: seq[JsonNode] elems*: seq[JsonNode]
@ -630,7 +630,7 @@ proc newJObject*(): JsonNode =
## Creates a new `JObject JsonNode` ## Creates a new `JObject JsonNode`
new(result) new(result)
result.kind = JObject result.kind = JObject
result.fields = initTable[string, JsonNode](4) result.fields = initOrderedTable[string, JsonNode](4)
proc newJArray*(): JsonNode = proc newJArray*(): JsonNode =
## Creates a new `JArray JsonNode` ## Creates a new `JArray JsonNode`
@ -670,8 +670,8 @@ proc getBVal*(n: JsonNode, default: bool = false): bool =
else: return n.bval else: return n.bval
proc getFields*(n: JsonNode, proc getFields*(n: JsonNode,
default = initTable[string, JsonNode](4)): default = initOrderedTable[string, JsonNode](4)):
Table[string, JsonNode] = OrderedTable[string, JsonNode] =
## Retrieves the key, value pairs of a `JObject JsonNode`. ## Retrieves the key, value pairs of a `JObject JsonNode`.
## ##
## Returns ``default`` if ``n`` is not a ``JObject``, or if ``n`` is nil. ## Returns ``default`` if ``n`` is not a ``JObject``, or if ``n`` is nil.
@ -760,7 +760,7 @@ proc toJson(x: NimNode): NimNode {.compiletime.} =
result = prefix(result, "%") result = prefix(result, "%")
macro `%*`*(x: expr): expr = macro `%*`*(x: untyped): untyped =
## Convert an expression to a JsonNode directly, without having to specify ## Convert an expression to a JsonNode directly, without having to specify
## `%` for every element. ## `%` for every element.
result = toJson(x) result = toJson(x)
@ -773,23 +773,29 @@ proc `==`* (a,b: JsonNode): bool =
elif b.isNil or a.kind != b.kind: elif b.isNil or a.kind != b.kind:
return false return false
else: else:
return case a.kind case a.kind
of JString: of JString:
a.str == b.str result = a.str == b.str
of JInt: of JInt:
a.num == b.num result = a.num == b.num
of JFloat: of JFloat:
a.fnum == b.fnum result = a.fnum == b.fnum
of JBool: of JBool:
a.bval == b.bval result = a.bval == b.bval
of JNull: of JNull:
true result = true
of JArray: of JArray:
a.elems == b.elems result = a.elems == b.elems
of JObject: of JObject:
a.fields == b.fields # we cannot use OrderedTable's equality here as
# the order does not matter for equality here.
if a.fields.len != b.fields.len: return false
for key, val in a.fields:
if not b.fields.hasKey(key): return false
if b.fields[key] != val: return false
result = true
proc hash*(n: Table[string, JsonNode]): Hash {.noSideEffect.} proc hash*(n: OrderedTable[string, JsonNode]): Hash {.noSideEffect.}
proc hash*(n: JsonNode): Hash = proc hash*(n: JsonNode): Hash =
## Compute the hash for a JSON node ## Compute the hash for a JSON node
@ -807,9 +813,9 @@ proc hash*(n: JsonNode): Hash =
of JString: of JString:
result = hash(n.str) result = hash(n.str)
of JNull: of JNull:
result = hash(0) result = Hash(0)
proc hash*(n: Table[string, JsonNode]): Hash = proc hash*(n: OrderedTable[string, JsonNode]): Hash =
for key, val in n: for key, val in n:
result = result xor (hash(key) !& hash(val)) result = result xor (hash(key) !& hash(val))
result = !$result result = !$result

View file

@ -10,6 +10,8 @@ Some text here.
Changes affecting backwards compatibility Changes affecting backwards compatibility
----------------------------------------- -----------------------------------------
- The ``json`` module uses an ``OrderedTable`` rather than a ``Table``
for JSON objects.
- De-deprecated ``re.nim`` because we have too much code using it - De-deprecated ``re.nim`` because we have too much code using it
and it got the basic API right. and it got the basic API right.