Last active
March 13, 2017 09:09
-
-
Save stisa/fa48fb24ba0929b42c7b39b2a0505029 to your computer and use it in GitHub Desktop.
Json -> SomeType conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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