Skip to content

Instantly share code, notes, and snippets.

@treeform
Created February 11, 2023 18:17
Show Gist options
  • Save treeform/4b1e85dab83217e3807315d64f3a5cd7 to your computer and use it in GitHub Desktop.
Save treeform/4b1e85dab83217e3807315d64f3a5cd7 to your computer and use it in GitHub Desktop.
import jsony, options
type
Cat = object
name: string
MyType = object
cat: Option[seq[Cat]]
let
d1 = """{"cat":[{"name":"sparky"}]}"""
d2 = """{"cat":{"name":"sparky"}}"""
d3 = """{"cat":null}"""
proc parseHook(s: string, i: var int, v: var Option[seq[Cat]]) =
eatSpace(s, i)
if i + 3 < s.len and
s[i+0] == 'n' and
s[i+1] == 'u' and
s[i+2] == 'l' and
s[i+3] == 'l':
i += 4
return
if s[i] == '[':
var v2: seq[Cat]
parseHook(s, i, v2)
v = some(v2)
else:
var v2: Cat
parseHook(s, i, v2)
v = some(@[v2])
echo d1.fromJson(MyType).cat
echo d2.fromJson(MyType).cat
echo d3.fromJson(MyType).cat
@lantos1618
Copy link

Works! with generics also

import jsony, options

type
  Cat = object
    name: string
  MyType = object
    cat: Option[seq[Cat]]

let
  d1 = """{"cat":[{"name":"sparky"}]}"""
  d2 = """{"cat":{"name":"sparky"}}"""
  d3 = """{"cat":null}"""

proc parseHook*[T](s: string, i: var int, v: var Option[seq[T]]) =
  eatSpace(s, i)
  if i + 3 < s.len and
      s[i+0] == 'n' and
      s[i+1] == 'u' and
      s[i+2] == 'l' and
      s[i+3] == 'l':
    i += 4
    return
  if s[i] == '[':
    var v2: seq[T]
    parseHook(s, i, v2)
    v = some(v2)
  else:
    var v2: T
    parseHook(s, i, v2)
    v = some(@[v2])

echo d1.fromJson(MyType).cat
echo d2.fromJson(MyType).cat
echo d3.fromJson(MyType).cat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment