diff options
author | flaviut <tamasflaviu@gmail.com> | 2014-05-26 16:13:19 -0400 |
---|---|---|
committer | flaviut <tamasflaviu@gmail.com> | 2014-05-26 16:13:19 -0400 |
commit | c7a57dc184ba5757c34884da44ed1b75dc150101 (patch) | |
tree | 071d896cfe38fe76abd830a0426a8841b21968fd /lib | |
parent | ec59b790c52223ff8c8f3f489005df1b6e4a51b6 (diff) | |
download | Nim-c7a57dc184ba5757c34884da44ed1b75dc150101.tar.gz |
Switch chaining to the `{}` and `{}=` operators
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/json.nim | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 4d6ecb837..a450a340c 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -628,29 +628,26 @@ proc len*(n: PJsonNode): int = of JObject: result = n.fields.len else: discard -proc `[]`*(node: PJsonNode, name: string, default: PJsonNode = nil): PJsonNode = - ## Gets a field from a `JObject`. If node is nil, this returns `default` - ## This is to allow for chaining such as the following: - ## .. code-block Nimrod - ## foo["field1"]["field2"] - ## - ## If `field1` is undefined, it will return nil, and the access on `field2` will - ## pass through and return `default`. Also returns `default` if the key is not found. +proc `[]`*(node: PJsonNode, name: string): PJsonNode + {.raises: [EInvalidValue].} = + ## Gets a field from a `JObject`. If `node` is nil, raises an + ## `EInvalidValue` exception. If the value at `name` does not + ## exist, returns nil if isNil(node): - return default + raise newException(EInvalidValue, "node may not be nil") assert(node.kind == JObject) for key, item in items(node.fields): if key == name: return item - return default + return nil -proc `[]`*(node: PJsonNode, index: int, default: PJsonNode = nil): PJsonNode {.raises: [EInvalidIndex].}= - ## Gets the node at `index` in an Array.If `node` is nil, this returns `result`, - ## which is by default `nil` to allow for chaining. `EInvalidIndex` is raised if `index` +proc `[]`*(node: PJsonNode, index: int): PJsonNode + {.raises: [EInvalidIndex, EInvalidValue].} = + ## Gets the node at `index` in an Array. `EInvalidIndex` is raised if `index` ## is out of bounds - if isNil(node): - return default assert(node.kind == JArray) + if isNil(node): + raise newException(EInvalidValue, "node may not be nil") if index < 0 or index >= node.elems.len: raise newException(EInvalidIndex, "index " & $index & " is out of range [0, " & $node.elems.len & ")") @@ -686,6 +683,25 @@ proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = return obj.fields.add((key, val)) +proc `{}`*(node: PJsonNode, names: varargs[string]): PJsonNode = + ## Transverses the node and gets the given value. If any of the + ## names does not exist, returns nil + result = node + for name in names: + result = result[name] + if isNil(result): + return nil + +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) @@ -942,12 +958,10 @@ when isMainModule: let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" # nil passthrough - assert(testJson["doesnt_exist"][1] == nil) - assert(testJson["doesnt_exist"]["anything"] == nil) - # default param - assert(testJson["doesnt_exist",%true].bval) - assert(testJson["doesnt_exist"][1,%true].bval) - + assert(testJson{"doesnt_exist", "anything"} == nil) + testJson{["c", "d"]} = %true + assert(testJson["c"]["d"].bval) + # Bounds checking try: let a = testJson["a"][9] |