Rewrite some of `%`
This commit is contained in:
parent
713f9d00d3
commit
30bfaa8c00
|
@ -3,7 +3,7 @@
|
|||
import bigints
|
||||
import std/[base64, endians, hashes, macros, sets, streams, tables, typetraits]
|
||||
|
||||
import json except `%`
|
||||
import json except `%`, `%*`
|
||||
|
||||
type
|
||||
PreserveKind* = enum
|
||||
|
@ -470,6 +470,91 @@ proc parsePreserve*(s: Stream): Preserve =
|
|||
else:
|
||||
assertStream(false)
|
||||
|
||||
proc initDictionary*(): Preserve = Preserve(kind: pkDictionary)
|
||||
|
||||
proc `%`*(b: bool): Preserve =
|
||||
Preserve(kind: pkBoolean, bool: b)
|
||||
|
||||
proc `%`*(f: float32): Preserve =
|
||||
Preserve(kind: pkFloat, float: f)
|
||||
|
||||
proc `%`*(d: float64): Preserve =
|
||||
Preserve(kind: pkDouble, double: d)
|
||||
|
||||
proc `%`*(n: SomeInteger): Preserve =
|
||||
Preserve(kind: pkSignedInteger, int: n)
|
||||
|
||||
proc `%`*(b: Bigint): Preserve =
|
||||
Preserve(kind: pkBigInteger, bigint: b)
|
||||
|
||||
proc `%`*(s: string): Preserve =
|
||||
Preserve(kind: pkString, string: s)
|
||||
|
||||
proc `%`*(buf: openarray[byte]): Preserve =
|
||||
Preserve(kind: pkByteString, bytes: @buf)
|
||||
|
||||
proc `%`*(e: enum): Preserve =
|
||||
## Initialize a preserves symbol from the string
|
||||
## representation of ``e``.
|
||||
Preserve(kind: pkSymbol, symbol: $e)
|
||||
|
||||
template `%`*(p: Preserve): Preserve = p
|
||||
|
||||
proc `%`*[T](elems: openArray[T]): Preserve =
|
||||
result = Preserve(kind: pkSequence,
|
||||
sequence: newSeqOfCap[Preserve](elems.len))
|
||||
for e in elems: result.sequence.add(%e)
|
||||
|
||||
proc `%`*[A,B](pairs: openArray[(A, B)]): Preserve =
|
||||
result = Preserve(kind: pkDictionary)
|
||||
for (k, v) in pairs:
|
||||
when A is string:
|
||||
result.dict[symbol k] = %v
|
||||
else:
|
||||
result.dict[%k] = %v
|
||||
|
||||
proc `%`*[T](set: HashSet[T]): Preserve =
|
||||
result = Preserve(kind: pkSet #[, set: set.map(`%`)]#)
|
||||
for e in set:
|
||||
result.set.incl %e
|
||||
|
||||
proc `%`*[A,B](table: Table[A,B]|TableRef[A,B]): Preserve =
|
||||
result = Preserve(kind: pkDictionary, dict: initTable[Preserve, Preserve](table.len))
|
||||
for k, v in table.pairs: result.dict[%k] = %v
|
||||
|
||||
proc `%`*[T: object](o: T): Preserve =
|
||||
## Construct JsonNode from tuples and objects.
|
||||
result = initDictionary()
|
||||
for k, v in o.fieldPairs: result.dict[symbol(k)] = %v
|
||||
|
||||
proc percentImpl(x: NimNode): NimNode {.compileTime.} =
|
||||
case x.kind
|
||||
of nnkBracket: # sequence
|
||||
result = newNimNode(nnkBracket)
|
||||
for i in 0 ..< x.len:
|
||||
result.add(percentImpl(x[i]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkTableConstr: # dictionary
|
||||
if x.len == 0: return newCall(bindSym"initDictionary")
|
||||
result = newNimNode(nnkTableConstr)
|
||||
for i in 0 ..< x.len:
|
||||
x[i].expectKind nnkExprColonExpr
|
||||
result.add newTree(nnkExprColonExpr, x[i][0], percentImpl(x[i][1]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkCurly: # set
|
||||
result = newNimNode(nnkCurly)
|
||||
for i in 0 ..< x.len:
|
||||
result.add(percentImpl(x[i]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkPar:
|
||||
if x.len == 1: result = percentImpl(x[0])
|
||||
else: result = newCall(bindSym("%", brOpen), x)
|
||||
else:
|
||||
result = newCall(bindSym("%", brOpen), x)
|
||||
|
||||
macro `%*`*(x: untyped): untyped =
|
||||
result = percentImpl(x)
|
||||
|
||||
template record*(label: string) {.pragma.}
|
||||
## Serialize this object or tuple as a record.
|
||||
## ```
|
||||
|
@ -521,7 +606,7 @@ proc toPreserve*[T](x: T): Preserve =
|
|||
elif T is SomeInteger:
|
||||
result = Preserve(kind: pkSignedInteger, int: x.BiggestInt)
|
||||
else:
|
||||
raiseAssert("cannot convert to Preserves: " & $T)
|
||||
result = %x
|
||||
|
||||
proc toPreserveHook*[T](set: HashSet[T]): Preserve =
|
||||
Preserve(kind: pkSet, set: set.map(toPreserve))
|
||||
|
@ -642,7 +727,7 @@ proc fromPreserve*[T](result: var T; prs: Preserve) =
|
|||
elif T is string:
|
||||
result = prs.string
|
||||
else:
|
||||
raiseAssert("cannot convert from Preserves: " & $T)
|
||||
static: raiseAssert("cannot convert from Preserves: " & $T)
|
||||
|
||||
proc preserveTo*(prs: Preserve; T: typedesc): T =
|
||||
## Reverse of `toPreserve`.
|
||||
|
@ -663,73 +748,3 @@ proc `[]`*(prs: Preserve; i: int): Preserve =
|
|||
of pkSequence: prs.sequence[i]
|
||||
else:
|
||||
raise newException(ValueError, "`[]` is not valid for " & $prs.kind)
|
||||
|
||||
template `%`*(p: Preserve): Preserve = p
|
||||
|
||||
proc `%`*(b: bool): Preserve =
|
||||
Preserve(kind: pkBoolean, bool: b)
|
||||
|
||||
proc `%`*(f: float32): Preserve =
|
||||
Preserve(kind: pkFloat, float: f)
|
||||
|
||||
proc `%`*(d: float64): Preserve =
|
||||
Preserve(kind: pkDouble, double: d)
|
||||
|
||||
proc `%`*(n: SomeInteger): Preserve =
|
||||
Preserve(kind: pkSignedInteger, int: n)
|
||||
|
||||
proc `%`*(b: Bigint): Preserve =
|
||||
Preserve(kind: pkBigInteger, bigint: b)
|
||||
|
||||
proc `%`*(s: string): Preserve =
|
||||
Preserve(kind: pkString, string: s)
|
||||
|
||||
proc `%`*(buf: seq[byte]): Preserve =
|
||||
Preserve(kind: pkByteString, bytes: buf)
|
||||
|
||||
proc `%`*(e: enum): Preserve =
|
||||
## Initialize a preserves symbol from the string
|
||||
## representation of ``e``.
|
||||
Preserve(kind: pkSymbol, symbol: $e)
|
||||
|
||||
proc `%`*[T](elems: openArray[T]): Preserve =
|
||||
result = Preserve(kind: pkSequence,
|
||||
sequence: newSeqOfCap[Preserve](elems.len))
|
||||
for e in elems: result.sequence.add(%e)
|
||||
|
||||
proc `%`*[T](set: HashSet[T]): Preserve =
|
||||
result = Preserve(kind: pkSet #[, set: set.map(`%`)]#)
|
||||
for e in set:
|
||||
result.set.incl %e
|
||||
|
||||
proc `%`*[A,B](table: Table[A,B]|TableRef[A,B]): Preserve =
|
||||
result = Preserve(kind: pkDictionary, dict: initTable[Preserve, Preserve](table.len))
|
||||
for k, v in table.pairs: result.dict[%k] = %v
|
||||
|
||||
proc toPreserveImpl(x: NimNode): NimNode {.compileTime.} =
|
||||
case x.kind
|
||||
of nnkBracket: # sequence
|
||||
result = newNimNode(nnkBracket)
|
||||
for i in 0 ..< x.len:
|
||||
result.add(toPreserveImpl(x[i]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkTableConstr: # dictionary
|
||||
if x.len == 0: return newCall(bindSym"newJObject")
|
||||
result = newNimNode(nnkTableConstr)
|
||||
for i in 0 ..< x.len:
|
||||
x[i].expectKind nnkExprColonExpr
|
||||
result.add newTree(nnkExprColonExpr, x[i][0], toPreserveImpl(x[i][1]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkCurly: # set
|
||||
result = newNimNode(nnkCurly)
|
||||
for i in 0 ..< x.len:
|
||||
result.add(toPreserveImpl(x[i]))
|
||||
result = newCall(bindSym("%", brOpen), result)
|
||||
of nnkPar:
|
||||
if x.len == 1: result = toPreserveImpl(x[0])
|
||||
else: result = newCall(bindSym("%", brOpen), x)
|
||||
else:
|
||||
result = newCall(bindSym("%", brOpen), x)
|
||||
|
||||
macro `%*`*(x: untyped): untyped =
|
||||
result = toPreserveImpl(x)
|
||||
|
|
|
@ -24,20 +24,6 @@ type RecordClass* = object
|
|||
proc `$`*(rec: RecordClass): string =
|
||||
$rec.label & "/" & $rec.arity
|
||||
|
||||
proc `%`*(rec: RecordClass; field: Preserve): Preserve =
|
||||
## Initialize a simple record value.
|
||||
assert(rec.arity == 1)
|
||||
Preserve(kind: pkRecord, record: @[field, rec.label])
|
||||
|
||||
proc `%`*[T](rec: RecordClass; field: T): Preserve =
|
||||
## Initialize a simple record value.
|
||||
rec % toPreserve(field)
|
||||
|
||||
proc init*(rec: RecordClass; fields: varargs[Preserve, toPreserve]): Preserve =
|
||||
## Initialize a new record value.
|
||||
assert(fields.len == rec.arity)
|
||||
result = initRecord(rec.label, fields)
|
||||
|
||||
proc isClassOf*(rec: RecordClass; val: Preserve): bool =
|
||||
## Compare the label and arity of ``val`` to the record type ``rec``.
|
||||
if val.kind == pkRecord:
|
||||
|
@ -63,3 +49,28 @@ proc classOf*(T: typedesc[tuple]): RecordClass =
|
|||
RecordClass(
|
||||
label: preserves.symbol(T.getCustomPragmaVal(record)),
|
||||
arity: tupleLen(T))
|
||||
|
||||
proc init*(rec: RecordClass; fields: varargs[Preserve, toPreserve]): Preserve =
|
||||
## Initialize a new record value.
|
||||
assert(fields.len == rec.arity, $(%fields) & " (arity " & $fields.len & ") is not of arity " & $rec.arity)
|
||||
result = initRecord(rec.label, fields)
|
||||
|
||||
proc init*(T: typedesc[tuple]; fields: varargs[Preserve, toPreserve]): Preserve =
|
||||
## Initialize a new record value.
|
||||
init(classOf(T), fields)
|
||||
|
||||
proc `%`*(rec: RecordClass; fields: openArray[Preserve]): Preserve =
|
||||
## Initialize a simple record value.
|
||||
init(rec, fields)
|
||||
|
||||
proc `%`*(rec: RecordClass; field: Preserve): Preserve =
|
||||
## Initialize a simple record value.
|
||||
init(rec, [field])
|
||||
|
||||
proc `%`*[T](rec: RecordClass; field: T): Preserve =
|
||||
## Initialize a simple record value.
|
||||
init(rec, [toPreserve field])
|
||||
|
||||
proc `%`*(T: typedesc[tuple]; fields: varargs[Preserve, toPreserve]): Preserve =
|
||||
## Initialize a new record value.
|
||||
`%`(classOf(T), fields)
|
||||
|
|
Loading…
Reference in New Issue