treeform / jsony

A loose, direct to object json parser with hooks.
MIT License
270 stars 34 forks source link

what if I don't want the default behaviour of `enum` ? #77

Open hamidb80 opened 1 year ago

hamidb80 commented 1 year ago

Hey,

I just want to store enums as ints,

wrapper.nim:

import jsony
import inner

type
    Enum = enum
        e1
        e2

echo fromJson("0", Enum)

inner.nim

import std/[parseutils]

proc parseHook*[T: enum](s: string, i: var int, v: var T) =
  var temp: int
  inc i, parseInt(s, temp, i)
  v = T temp

proc dumpHook*(s: var string, v: enum) =
  s.add $v.int

Expected behaviour

compiles successfully and considers enums as ints

Current output

/wrapper.nim(10, 14) template/generic instantiation of `fromJson` from here
/.nimble/jsony/jsony.nim(590, 4) 

Error: ambiguous call; both 

jsony.parseHook(s: string, i: var int, v: var T: enum) [proc declared in /.nimble/jsony/jsony.nim(406, 6)] 
and 
inner.parseHook(s: string, i: var int, v: var T: enum) [proc declared in inner.nim(3, 6)] 

match for: (string, int, Enum)
hamidb80 commented 1 year ago

mixing wrapper.nim and inner.nim works fine, but I cannot separate them

as a quick workaround I made a file called jsony_fix.nim:

import std/parseutils
proc parseHook*[T: enum](s: string, i: var int, v: var T) =
  var temp: int
  inc i, parseInt(s, temp, i)
  v = T temp

proc dumpHook*(s: var string, v: enum) =
  s.add $v.int

and include it wherever I import Jsony:

import jsony
include jsony_fix
treeform commented 1 year ago

Hey,

This is because you are trying to override a library function precisely. I'm not sure what the best solution is. If you had proc parseHook*[MyEnum], it would work. But you seem to want to override the general one. I'm not certain Nim supports this. I'm glad you found a workaround.