Hello,
I have been working on an app which calls a REST api which returns json objects.
I have created the types and when I attempt to convert I get this error.
lib/system.nim(2833, 7) Error: unhandled exception: false Unable to process nnkSym DateTime
It is probably a simple newbie error. But I am failing to see why it fails or how to fix.
Any help greatly appreciated.
Here is from what I see the pertinent code.
type
DateTime* = string
Price* = object
time*: DateTime
...
proc test_prices(data: string): seq[Price] =
let jsonNode = parseJson(data)
echo($jsonNode)
result = to(jsonNode, Price)
Thanks.
I think the Marshal module can help you there
Noooo. Please read the marshal module's docs:
The serialization format uses JSON. Warning: The serialization format could change in future!
Do not use marshal for JSON!
He is doing an API with a REST API, if he controls both the application and the client, he can use marshal.
Now, so far we only know that he owns the application and we don't know if the client(s) are also in Nim.
The below fails with the same error.
type
DateTime* = string
response = """
{
"datetime":"2016-06-22T18:41:36.042678456Z"
}
"""
var data = parseJson(response)
echo(to(data, DateTime))
If I am doing something wrong. I am okay with that. But I don't see what it is.
I have this app mostly written in Python. I might simply need to finish version 1 with Python and revisit Nim when I have more time to be better at Nim.
I am in complete control of my app and all client side code. The only thing I don't control over is the REST api coming from the third party servers. I am a consumer and also producer of json to them in the requests.
Thanks for your help.
Running into this, still seems to be a bug.
I have a simple type:
type
Torrent* = object
name*: string
uploaded_at*: DateTime
And when I try to render a seq[Torrent] in my jester API as json:
Users/sergiotapia/Work/torrentinim/src/torrentinim.nim(18, 14) template/generic instantiation of `%*` from here
/Users/sergiotapia/.choosenim/toolchains/nim-1.0.4/lib/pure/json.nim(331, 36) template/generic instantiation of `%` from here
/Users/sergiotapia/.choosenim/toolchains/nim-1.0.4/lib/pure/json.nim(371, 14) template/generic instantiation of `%` from here
/Users/sergiotapia/.choosenim/toolchains/nim-1.0.4/lib/pure/json.nim(364, 41) Error: type mismatch: got <proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}>
but expected one of:
proc `%`(s: string): JsonNode
first type mismatch at position: 1
required type for s: string
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(n: uint): JsonNode
first type mismatch at position: 1
required type for n: uint
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(n: BiggestInt): JsonNode
first type mismatch at position: 1
required type for n: BiggestInt
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(n: BiggestUInt): JsonNode
first type mismatch at position: 1
required type for n: BiggestUInt
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(n: int): JsonNode
first type mismatch at position: 1
required type for n: int
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(n: float): JsonNode
first type mismatch at position: 1
required type for n: float
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(b: bool): JsonNode
first type mismatch at position: 1
required type for b: bool
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode
first type mismatch at position: 1
required type for keyVals: openArray[tuple[key: string, val: JsonNode]]
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
template `%`(j: JsonNode): JsonNode
first type mismatch at position: 1
required type for j: JsonNode
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`[T](elements: openArray[T]): JsonNode
first type mismatch at position: 1
required type for elements: openArray[T]
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`[T](table: Table[string, T] | OrderedTable[string, T]): JsonNode
first type mismatch at position: 1
required type for table: Table[system.string, %.T] or OrderedTable[system.string, %.T]
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`[T](opt: Option[T]): JsonNode
first type mismatch at position: 1
required type for opt: Option[%.T]
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`[T: object](o: T): JsonNode
first type mismatch at position: 1
required type for o: T: object
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(formatstr, a: string): string
first type mismatch at position: 1
required type for formatstr: string
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(formatstr: string; a: openArray[string]): string
first type mismatch at position: 1
required type for formatstr: string
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(f: string; t: StringTableRef; flags: set[FormatFlag] = {}): string
first type mismatch at position: 1
required type for f: string
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(o: enum): JsonNode
first type mismatch at position: 1
required type for o: enum
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
proc `%`(o: ref object): JsonNode
first type mismatch at position: 1
required type for o: ref object
but expression 'o.zonedTimeFromTimeImpl' is of type: proc (x: Time): ZonedTime{.closure, gcsafe, locks: 0.}
expression: %o.zonedTimeFromTimeImpl
BSON uses Extended Json (v2); and BSON does have a UTC Time/Date function. Granted, it converts to Time rather than DateTime. BSON also has marshalling support to/from objects.
If interested in that: https://nimble.directory/pkg/bson
Example of use with objects:
import json
import times
import bson
import bson/marshal
type
MyType = object
cannonicalDate: Time
relaxedDate: Time
marshal(MyType)
let example = """{
"cannonicalDate": {"$date": {"$numberLong": "1567367316000"}},
"relaxedDate": {"$date": "2019-08-11T17:54:14"},
}"""
let parsedJsonDoc = parseJson(example)
let bsonDoc = interpretExtendedJson(parsedJsonDoc)
var exampleObj = MyType()
exampleObj.pull(bsonDoc) # this applies the BSON to the object
assert exampleObj.relaxedDate.format("yyyy-MM-dd\'T\'HH:mm:ss", utc()) == "2019-08-11T17:54:14"
But, this does not solve the original poster's problem if the JSON he receives is not ExtendedJSON compliant.
As to modifying the library, IMO Araq is correct, since JSON does not support dates, putting such support into the standard library would be improper. Someone could write a nimble support library though.