mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-24 05:23:16 +00:00
54 lines
1.6 KiB
Nim
54 lines
1.6 KiB
Nim
## Generic payload encoding.
|
|
##
|
|
## Symmetric with `keys.nim`: reuses the same `encodePart` family so any
|
|
## Nim type composable from primitives + tuples/objects can be turned
|
|
## into a `seq[byte]` for storage. Unlike keys, payloads do **not** need
|
|
## byte-wise lex order — but using the same encoder keeps the system
|
|
## small. If a tenant needs a different on-disk format (CBOR, protobuf,
|
|
## SSZ, ...) they can write their own `toPayload` overload or pass an
|
|
## already-encoded `seq[byte]` to `persistPut`.
|
|
##
|
|
## ```nim
|
|
## # Primitives:
|
|
## let p1 = payload("hello") # length-prefixed string bytes
|
|
## let p2 = payload(42'i64) # 8 bytes, sign-flipped BE
|
|
##
|
|
## # Composites:
|
|
## type Msg = object
|
|
## sender: string
|
|
## epoch: int64
|
|
## body: seq[byte]
|
|
## let p3 = toPayload(Msg(sender: "alice", epoch: 7, body: @[1'u8, 2, 3]))
|
|
##
|
|
## # Variadic when you want multiple values back-to-back:
|
|
## let p4 = payload("v1", 1'i64, body)
|
|
## ```
|
|
|
|
{.push raises: [].}
|
|
|
|
import std/macros
|
|
import ./keys
|
|
|
|
export keys.encodePart
|
|
|
|
proc toPayload*[T](v: T): seq[byte] =
|
|
## Single-value payload constructor. Equivalent to `payload(v)`.
|
|
var buf: seq[byte] = @[]
|
|
encodePart(buf, v)
|
|
return buf
|
|
|
|
macro payload*(parts: varargs[typed]): seq[byte] =
|
|
## Variadic payload builder. Same encoder as `key(...)`; only the return
|
|
## type differs.
|
|
let bufSym = genSym(nskVar, "payloadBuf")
|
|
var body = newStmtList()
|
|
body.add quote do:
|
|
var `bufSym`: seq[byte] = @[]
|
|
for p in parts:
|
|
body.add quote do:
|
|
encodePart(`bufSym`, `p`)
|
|
body.add bufSym
|
|
return newBlockStmt(body)
|
|
|
|
{.pop.}
|