summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2015-02-07 18:34:35 +0100
committerAndreas Rumpf <rumpf_a@web.de>2015-02-07 18:34:35 +0100
commitb25346719d3726d9b11fcdc64ad07d6da2ad7007 (patch)
treedb8fd899923bf739998256dacd72cc0a8a6a437b
parent28af09a44696c29572ea920b3c458eca1f1e967e (diff)
parentf3922bc4e5f2d01e8b594fbe30f24b2619bec993 (diff)
downloadNim-b25346719d3726d9b11fcdc64ad07d6da2ad7007.tar.gz
Merge pull request #1869 from def-/json-stuff
Json stuff
-rw-r--r--lib/pure/json.nim77
1 files changed, 75 insertions, 2 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 873e4b78e..2a40b4f1f 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -30,9 +30,28 @@
 ##
 ##   1.3000000000000000e+00
 ##   true
+##
+## This module can also be used to comfortably create JSON using the `%*`
+## operator:
+##
+## .. code-block:: nim
+##
+##   var hisName = "John"
+##   let herAge = 31
+##   var j = %*
+##     [
+##       {
+##         "name": hisName,
+##         "age": 30
+##       },
+##       {
+##         "name": "Susan",
+##         "age": herAge
+##       }
+##     ]
 
 import 
-  hashes, strutils, lexbase, streams, unicode
+  hashes, strutils, lexbase, streams, unicode, macros
 
 type 
   JsonEventKind* = enum  ## enumeration of all events that may occur when parsing
@@ -625,6 +644,29 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
   newSeq(result.elems, elements.len)
   for i, p in pairs(elements): result.elems[i] = p
 
+proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
+  case x.kind
+  of nnkBracket:
+    result = newNimNode(nnkBracket)
+    for i in 0 .. <x.len:
+      result.add(toJson(x[i]))
+
+  of nnkTableConstr:
+    result = newNimNode(nnkTableConstr)
+    for i in 0 .. <x.len:
+      assert x[i].kind == nnkExprColonExpr
+      result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1])))
+
+  else:
+    result = x
+
+  result = prefix(result, "%")
+
+macro `%*`*(x: expr): expr =
+  ## Convert an expression to a JsonNode directly, without having to specify
+  ## `%` for every element.
+  result = toJson(x)
+
 proc `==`* (a,b: JsonNode): bool =
   ## Check two nodes for equality
   if a.isNil:
@@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string =
 proc `$`*(node: JsonNode): string =
   ## Converts `node` to its JSON Representation on one line.
   result = ""
-  toPretty(result, node, 1, false)
+  toPretty(result, node, 0, false)
 
 iterator items*(node: JsonNode): JsonNode =
   ## Iterator for the items of `node`. `node` has to be a JArray.
@@ -1101,6 +1143,37 @@ when isMainModule:
   except:
     assert(false, "EInvalidIndex thrown for valid index")
 
+  # Generator:
+  var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
+  assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
+  var j2 = %*
+    [
+      {
+        "name": "John",
+        "age": 30
+      },
+      {
+        "name": "Susan",
+        "age": 31
+      }
+    ]
+  assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
+  var name = "John"
+  let herAge = 30
+  const hisAge = 31
+
+  var j3 = %*
+    [ { "name": "John"
+      , "age": herAge
+      }
+    , { "name": "Susan"
+      , "age": hisAge
+      }
+    ]
+  assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
   discard """
   while true:
     var json = stdin.readLine()