Hi, my custom data type contains times.DateTime:
import options, tables, times
import deser_json
type
    Data* = object
        shifts*: OrderedTable[int64, Shift]
        balance*: float
    
    Shift* = object
        quoted*: bool
        date*: DateTime
        description*: string
        start*: Option[DateTime]
        finish*: Option[DateTime]
        breakTime*: Option[Duration]
        rate*: float
        qty: Option[float]
        id*: int64
let shift = Shift(
    quoted: true,
    date: parse("2000-01-01", "yyyy-MM-dd"),
    description: "abcdef",
    start: none(DateTime),
    finish: none(DateTime),
    breakTime: none(Duration),
    rate: 462.11,
    qty: some(10.0),
    id: getTime().toUnix()
)
var shifts: OrderedTable[int64, Shift]
shifts[shift.id] = shift
let data = Data(
    shifts: shifts,
    balance: 0.00
)
assert data == data.dumps().parse().to(Data)
When I try to serialize/deserialize my type I get the following error:
/home/adnan338/.choosenim/toolchains/nim-1.4.2/lib/pure/times.nim(2110, 39) Hint: 'parse' cannot raise 'Defect' [XCannotRaiseY]
/tmp/serde.nim(39, 8) template/generic instantiation of `assert` from here
/home/adnan338/.nimble/pkgs/deser_json-0.2.1/deser_json.nim(341, 8) template/generic instantiation of `dumps` from here
/home/adnan338/.nimble/pkgs/deser_json-0.2.1/deser_json.nim(296, 17) template/generic instantiation of `forSerFields` from here
/home/adnan338/.nimble/pkgs/deser-0.1.4/deser/templates.nim(8, 15) Error: attempting to call undeclared routine: 'hasCustomPragma'
I was using deserjson in this code, I also tried nimyaml and serializetools and they also failed for different reasons. What package should supoort my data type?
I tried deser_json and I get the same errors. I fixed hasCustomPragma with import macros but then I get m.tokens[pos].kind == JSMN_OBJECT ... I don't know how to get around that one.
If you want to use json (for easier debugging or compatibility) take a look at these libraries they pass my tests:
name ............................... min time      avg time    std dv  times
treeform/jsony ..................... 1.531 ms      2.779 ms    ±0.091   x100
status-im/nim-json-serialization ... 2.043 ms      3.448 ms    ±0.746   x100
planetis-m/eminim .................. 5.951 ms      9.305 ms    ±3.210   x100
disruptek/jason ................... 10.312 ms     13.471 ms    ±3.107   x100
nim std/json ...................... 12.551 ms     19.419 ms    ±4.039   x100
name ............................... min time      avg time    std dv  times
treeform/jsony ..................... 6.724 ms     12.047 ms    ±3.694   x100
status-im/nim-json-serialization ... 7.119 ms     14.276 ms    ±2.033   x100
nim std/json ...................... 24.141 ms     38.741 ms    ±5.417   x100
planetis-m/eminim ................. 10.974 ms     18.355 ms    ±3.994   x100
https://github.com/treeform/jsony
But really if you want to go fast you might want a binary format instead of json:
name ............................... min time      avg time    std dv   runs
treeform/flatty .................... 3.615 ms      3.712 ms    ±0.084   x100
bingod/planetis-m .................. 6.632 ms      6.785 ms    ±0.105   x100
disruptek/frosty ................... 9.133 ms      9.294 ms    ±0.152   x100
treeform/jsony ..................... 7.746 ms      7.858 ms    ±0.081   x100
treeform/flatty .................... 7.849 ms     11.745 ms    ±0.157   x100
bingod/planetis-m binTo ............ 8.414 ms     13.114 ms    ±5.822   x100
disruptek/frosty .................. 29.689 ms     30.109 ms    ±0.309   x100
treeform/jsony .................... 60.054 ms     62.637 ms    ±0.616   x100
https://github.com/treeform/flatty
If a library fails to work try another one... if my library fails to work open a issue on github.
Looking at date time more, I don't think DateTime is a good candidate for serializing because it contains pointers to functions that determine timezone. How do you want to handle the timezones? I would recommend just stocking with unix epoc (seconds from 1970) if you don't want to make your life x100 harder by dealing with timezone sterilization.
I don't usually use DateTime (I use the https://github.com/treeform/chrono), but here is what I got:
import times, flatty
proc toFlatty(s: var string, x: DateTime) =
  s.toFlatty(x.toTime.toUnix)
proc fromFlatty(s: string, i: var int, x: var DateTime) =
  var
    unix: int64
  s.fromFlatty(i, unix)
  x = parse("1970-01-01", "yyyy-MM-dd", utc()) + initTimeInterval(seconds = unix.int)
var date = parse("2000-01-01", "yyyy-MM-dd", utc())
echo date
echo date.toFlatty().fromFlatty(type(date))
assert date == date.toFlatty().fromFlatty(type(date))