diff --git a/README.md b/README.md index ccd0dea..f5d4fcd 100644 --- a/README.md +++ b/README.md @@ -19,18 +19,23 @@ Making some assumptions (ie. that our types aren't changing) allows... - predictably _idiomatic_ API - **hard to misuse** -It's _fairly_ hard to misuse, but it's not fully optimized yet. In some cases, -it's much faster than the standard json module. In a few, it's a little slower. +It's _fairly_ hard to misuse, but it's not fully optimized yet. In most cases, +it's faster than the standard library's `json` module. In rare cases, you may +find it a little slower. -The main advantage is that you get JSON encoding of tuples, objects, and +Static values known at compile-time such as constants or macro outputs are +serialized at compile-time. This is orders of magnitude faster than the +standard library. + +But the main advantage is that you get JSON encoding of tuples, objects, and iterators "for free" -- no serialization to implement and no duplication of data. Everything is type-checked, too, so there will be no runtime serialization exceptions. -And, if you _want_ to implement custom serialization, it's now trivial to do -so for individual types. +And, if you _want_ to implement custom serialization, it's now trivial to do so +for individual types. You can also implement custom compile-time serialization. ## Usage @@ -89,10 +94,18 @@ type let b = B(x: 3, y: "sup") let c: C = @[ B(x: 1), B(x: 2), B(x: 3) ] +const a = B(x: 4, y: "compile-time!") + func jason(n: B): Json = + ## my special json encoding for B if n.x mod 2 == 0: jason"even" else: jason"odd" +macro jason(n: static[B]): Json = + ## compile-time json encoding is free! + newCall(ident"Json", newLit(n.jason.string)) + +echo a.jason # "even" echo b.jason # "odd" echo c.jason # ["odd","even","odd"] ``` diff --git a/jason.nim b/jason.nim index e2a24e7..b593ddc 100644 --- a/jason.nim +++ b/jason.nim @@ -27,7 +27,7 @@ proc join(a: openArray[Json]; sep = Json""): Json = # these are copied from stdlib so that we can be certain we match output # without having to import json and all of its dependencies... i know. -proc escapeJsonUnquoted(s: string; result: var string) = +proc escapeJsonUnquoted(s: string; result: var string) {.used.} = ## Converts a string `s` to its JSON representation without quotes. ## Appends to ``result``. for c in s: @@ -91,14 +91,6 @@ macro jason*(s: string): Json = let escapist = bindSym "escapeJson" result = json newCall(escapist, s) -macro jason*(s: static[string]): Json = - ## Escapes a static string to form "JSON". - runnableExamples: - const g = "goats" - assert jason(g) == """"goats"""" - - result = json newLit(escapeJson s) - macro jason*(b: bool): Json = ## Produce a JSON boolean, either `true` or `false`. runnableExamples: @@ -121,6 +113,22 @@ func jason*(f: SomeFloat): Json = ## Render any Nim float as a JSON number. result = Json($f) +when not defined(nimdoc): + macro jason*(j: static[string]): Json = json newLit(j.jason.string) + macro jason*(j: static[bool]): Json = json newLit(j.jason.string) + macro jason*(j: static[int]): Json = json newLit(j.jason.string) + macro jason*(j: static[int8]): Json = json newLit(j.jason.string) + macro jason*(j: static[int16]): Json = json newLit(j.jason.string) + macro jason*(j: static[int32]): Json = json newLit(j.jason.string) + macro jason*(j: static[int64]): Json = json newLit(j.jason.string) + macro jason*(j: static[uint]): Json = json newLit(j.jason.string) + macro jason*(j: static[uint8]): Json = json newLit(j.jason.string) + macro jason*(j: static[uint16]): Json = json newLit(j.jason.string) + macro jason*(j: static[uint32]): Json = json newLit(j.jason.string) + macro jason*(j: static[uint64]): Json = json newLit(j.jason.string) + macro jason*(j: static[float]): Json = json newLit(j.jason.string) + macro jason*(j: static[float32]): Json = json newLit(j.jason.string) + proc composeWithComma(parent: NimNode; js: NimNode): NimNode = # whether we need to add a comma before the next element let adder = bindSym "add" diff --git a/jason.nimble b/jason.nimble index 1489223..f3cc5c3 100644 --- a/jason.nimble +++ b/jason.nimble @@ -1,4 +1,4 @@ -version = "0.0.3" +version = "0.1.0" author = "disruptek" description = "compile-time json" license = "MIT" diff --git a/tests/test.nim b/tests/test.nim index a89437d..e66533a 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -93,13 +93,19 @@ testes: B = object x: int y: string + C = seq[B] + const a = B(x: 4, y: "compile-time!") let b = B(x: 3, y: "sup") + let c: C = @[ B(x: 1), B(x: 2), B(x: 3) ] func jason(n: B): Json = - if n.x == 3: - jason"odd" - else: - jason"even" + if n.x mod 2 == 0: jason"even" + else: jason"odd" + macro jason(n: static[B]): Json = + newCall(ident"Json", newLit(n.jason.string)) + + check a.jason == """"even"""" check b.jason == """"odd"""" + check c.jason == """["odd","even","odd"]"""