Code and the playground:
import strformat, json, strutils
type Price = tuple[price: float, currency: string]
proc init*(_: typedesc[Price], raw: string): Price =
let parts = raw.split(" ")
assert parts.len == 2, fmt"invalid price '{raw}'"
(parse_float(parts[0]), parts[1])
proc init*(_: typedesc[Price], price: float, currency: string): Price =
(price, currency)
func `$`*(v: Price): string =
fmt"{v.price} {v.currency}"
func `%`*(s: Price): JsonNode =
%($s)
proc init_from_json*(dst: var Price, json: JsonNode, json_path: string) =
dst = Price.init(json.get_str)
proc to_s*[T](v: T): string = $v
proc to_json*[T](v: T): string = (%v).pretty
# Testing
let price = Price.init(214.05, "USD")
assert price.to_s == "214.05 USD"
assert price.to_json == "214.05 USD" # Strange error N1
assert "214.05 USD".parse_json.to(Price) == Price.init(214.05, "USD") # JSON parsing error N2
No, it actually works, code below would work, try in playground
...
# Testing
echo "[\"214.05 USD\"]".parse_json.to(seq[Price])
I made a fast json parser that can parse wild json: https://github.com/treeform/jsony
Here is an example of parsing datetime: https://github.com/treeform/jsony#proc-parsehook-can-be-used-to-do-anything