diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2014-07-15 01:42:19 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2014-07-15 01:42:19 +0200 |
commit | 18ded6c23d72cd21fa0aa10ff61dc6f9af40832c (patch) | |
tree | 5d681c9835f01019e8ae83e14c0cd49d1a6c0d38 /lib/pure/json.nim | |
parent | 687a1b7de4c006750274fb046a10f08d38c22f5a (diff) | |
parent | 41bb0bf9dcccdfcebdb0f823fea8b2853b89ea4e (diff) | |
download | Nim-18ded6c23d72cd21fa0aa10ff61dc6f9af40832c.tar.gz |
Merge pull request #1363 from Araq/devel
Merge devel into master
Diffstat (limited to 'lib/pure/json.nim')
-rw-r--r-- | lib/pure/json.nim | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 4250847e5..508e564c5 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -619,6 +619,44 @@ proc `%`*(elements: openArray[PJsonNode]): PJsonNode = newSeq(result.elems, elements.len) for i, p in pairs(elements): result.elems[i] = p +proc `==`* (a,b: PJsonNode): bool = + ## Check two nodes for equality + if a.kind != b.kind: false + else: + case a.kind + of JString: + a.str == b.str + of JInt: + a.num == b.num + of JFloat: + a.fnum == b.fnum + of JBool: + a.bval == b.bval + of JNull: + true + of JArray: + a.elems == b.elems + of JObject: + a.fields == b.fields + +proc hash* (n:PJsonNode): THash = + ## Compute the hash for a JSON node + case n.kind + of JArray: + result = hash(n.elems) + of JObject: + result = hash(n.fields) + of JInt: + result = hash(n.num) + of JFloat: + result = hash(n.fnum) + of JBool: + result = hash(n.bval.int) + of JString: + result = hash(n.str) + of JNull: + result = hash(0) + proc len*(n: PJsonNode): int = ## If `n` is a `JArray`, it returns the number of elements. ## If `n` is a `JObject`, it returns the number of pairs. @@ -629,7 +667,9 @@ proc len*(n: PJsonNode): int = else: discard proc `[]`*(node: PJsonNode, name: string): PJsonNode = - ## Gets a field from a `JObject`. Returns nil if the key is not found. + ## Gets a field from a `JObject`, which must not be nil. + ## If the value at `name` does not exist, returns nil + assert(not isNil(node)) assert(node.kind == JObject) for key, item in items(node.fields): if key == name: @@ -637,7 +677,9 @@ proc `[]`*(node: PJsonNode, name: string): PJsonNode = return nil proc `[]`*(node: PJsonNode, index: int): PJsonNode = - ## Gets the node at `index` in an Array. + ## Gets the node at `index` in an Array. Result is undefined if `index` + ## is out of bounds + assert(not isNil(node)) assert(node.kind == JArray) return node.elems[index] @@ -671,6 +713,23 @@ proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = return obj.fields.add((key, val)) +proc `{}`*(node: PJsonNode, key: string): PJsonNode = + ## Transverses the node and gets the given value. If any of the + ## names does not exist, returns nil + result = node + if isNil(node): return nil + result = result[key] + +proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = + ## Transverses the node and tries to set the value at the given location + ## to `value` If any of the names are missing, they are added + var node = node + for i in 0..(names.len-2): + if isNil(node[names[i]]): + node[names[i]] = newJObject() + node = node[names[i]] + node[names[names.len-1]] = value + proc delete*(obj: PJsonNode, key: string) = ## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs. assert(obj.kind == JObject) @@ -996,6 +1055,28 @@ when isMainModule: raise newException(EInvalidValue, "That line was expected to fail") except EInvalidIndex: echo() + let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" + # nil passthrough + assert(testJson{"doesnt_exist"}{"anything"}.isNil) + testJson{["c", "d"]} = %true + assert(testJson["c"]["d"].bval) + + # Bounds checking + try: + let a = testJson["a"][9] + assert(false, "EInvalidIndex not thrown") + except EInvalidIndex: + discard + try: + let a = testJson["a"][-1] + assert(false, "EInvalidIndex not thrown") + except EInvalidIndex: + discard + try: + assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value") + except: + assert(false, "EInvalidIndex thrown for valid index") + discard """ while true: var json = stdin.readLine() |