Skip to content

Instantly share code, notes, and snippets.

@stisa
Last active March 13, 2017 09:09
Show Gist options
  • Save stisa/fa48fb24ba0929b42c7b39b2a0505029 to your computer and use it in GitHub Desktop.
Save stisa/fa48fb24ba0929b42c7b39b2a0505029 to your computer and use it in GitHub Desktop.
Json -> SomeType conversion
import json
#TODO: handle ref,ptr,tuple
proc into[T](json:seq[JsonNode],b:var openarray[T]) =
## Seq of Omogeneous JsonNodes into an array or seq of type T
for i,el in json:
when T is bool:
b[i] = el.bval
elif T is SomeInteger:
b[i] = el.num.int
elif T is SomeReal:
b[i] = el.fnum.float
elif T is string:
b[i] = el.str
elif T is array:
for j,ar in b.mpairs:
el.elems[j].into(ar)
elif T is seq:
b = @[]
b.setlen(el.elems.len)
el.elems.into(b)
elif T is object:
if not el.isnil: el.into(b)
#TODO: elif val is ref,ptr,tuple:
else:
{.error: "unhandled type"}
proc into*[T](json:JsonNode,b: var T) =
## Transforms a JsonNode into a Nim type
for key,val in fieldpairs(b):
when val is bool:
val = json.getOrDefault(key).bval
elif val is SomeInteger:
val = json.getOrDefault(key).num.int
elif val is SomeReal:
val = json.getOrDefault(key).fnum.float
elif val is string:
val = json.getOrDefault(key).str
elif val is array:
if json.hasKey(key):
json.getOrDefault(key).elems.into(val)
elif val is seq:
val = @[]
if json.hasKey(key):
val.setlen(json.getOrDefault(key).elems.len)
json.getOrDefault(key).elems.into(val)
elif val is object:
let json2 = json.getOrDefault(key)
if not json2.isnil: json2.into(val)
#TODO: elif val is ref,ptr,tuple:
else:
{.error: "unhandled type for key:" & key}
type B = object
a : float
b: seq[string]
type A = object
a: int
b: string
c: bool
d: float
e: B
f: array[3,int]
g: seq[string]
## Example ##
let a = """{
"a": 42,
"b": "hello",
"c":true,
"d": 1.31,
"e":{"a":1.3,"b":["hello","there"]},
"f":[1,2,3],
"g": ["somestr"]
}"""
var ajson = a.parsejson
var b : A
ajson.into(b)
echo b
echo repr b.f
#> (a: 42, b: hello, c: true, d: 1.31, e: (a: 1.3, b: @[hello, there]), f: ..., g: @[somestr])
#> [1, 2, 3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment