mirror of
https://github.com/logos-storage/nim-serde.git
synced 2026-01-08 08:33:09 +00:00
refactor: rename encode to toCbor and toCbor to toCborNode for consistency
This commit is contained in:
parent
9d3da40c0a
commit
0e2fd5c22d
@ -593,105 +593,6 @@ proc fromCbor*[T: tuple](_: type T, n: CborNode): ?!T =
|
||||
|
||||
success res
|
||||
|
||||
# proc fromCbor*[T](v: var T; n: CborNode): ?!void =
|
||||
# try:
|
||||
# when T is CborNode:
|
||||
# v = n
|
||||
# result = success()
|
||||
# elif compiles(fromCborHook(v, n)):
|
||||
# return fromCborHook(v, n)
|
||||
# elif T is distinct:
|
||||
# return fromCbor(distinctBase v, n)
|
||||
# elif T is SomeUnsignedInt:
|
||||
# expectCborKind(T, {cborUnsigned}, n)
|
||||
# v = T n.uint
|
||||
# if v.BiggestUInt == n.uint:
|
||||
# return success()
|
||||
# else:
|
||||
# return failure(newCborError("Value overflow for unsigned integer"))
|
||||
# elif T is SomeSignedInt:
|
||||
# expectCborKind(T, {cborUnsigned, cborNegative}, n)
|
||||
# if n.kind == cborUnsigned:
|
||||
# v = T n.uint
|
||||
# if v.BiggestUInt == n.uint:
|
||||
# return success()
|
||||
# else:
|
||||
# return failure(newCborError("Value overflow for un signed integer"))
|
||||
# elif n.kind == cborNegative:
|
||||
# v = T n.int
|
||||
# if v.BiggestInt == n.int:
|
||||
# return success()
|
||||
# else:
|
||||
# return failure(newCborError("Value overflow for signed integer"))
|
||||
# elif T is bool:
|
||||
# if not n.isBool:
|
||||
# return failure(newCborError("Expected boolean, got " & $n.kind))
|
||||
# v = n.getBool
|
||||
# return success()
|
||||
# elif T is SomeFloat:
|
||||
# expectCborKind(T, {cborFloat}, n)
|
||||
# v = T n.float
|
||||
# return success()
|
||||
# elif T is seq[byte]:
|
||||
# expectCborKind(T, {cborBytes}, n)
|
||||
# v = n.bytes
|
||||
# return success()
|
||||
# elif T is string:
|
||||
# expectCborKind(T, {cborText}, n)
|
||||
# v = n.text
|
||||
# return success()
|
||||
# elif T is seq:
|
||||
# expectCborKind(T, {cborArray}, n)
|
||||
# v.setLen n.seq.len
|
||||
# for i, e in n.seq:
|
||||
# let itemResult = fromCbor(v[i], e)
|
||||
# if itemResult.isFailure:
|
||||
# v.setLen 0
|
||||
# return failure(itemResult.error)
|
||||
# return success()
|
||||
# elif T is tuple:
|
||||
# expectCborKind(T, {cborArray}, n)
|
||||
# if n.seq.len != T.tupleLen:
|
||||
# return failure(newCborError("Expected tuple of length " & $T.tupleLen))
|
||||
# var i: int
|
||||
# for f in fields(v):
|
||||
# let itemResult = fromCbor(f, n.seq[i])
|
||||
# if itemResult.isFailure:
|
||||
# return failure(itemResult.error)
|
||||
# inc i
|
||||
# return success()
|
||||
# elif T is ref:
|
||||
# if n.isNull:
|
||||
# v = nil
|
||||
# return success()
|
||||
# else:
|
||||
# if isNil(v): new(v)
|
||||
# return fromCbor(v[], n)
|
||||
# elif T is object:
|
||||
# expectCborKind(T, {cborMap}, n)
|
||||
# var
|
||||
# i: int
|
||||
# key = CborNode(kind: cborText)
|
||||
# for s, _ in fieldPairs(v):
|
||||
# key.text = s
|
||||
# if not n.map.hasKey key:
|
||||
# return failure(newCborError("Missing field: " & s))
|
||||
# else:
|
||||
# let fieldResult = fromCbor(v.dot(s), n.map[key])
|
||||
# if fieldResult.isFailure:
|
||||
# return failure(fieldResult.error)
|
||||
# inc i
|
||||
# if i == n.map.len:
|
||||
# return success()
|
||||
# else:
|
||||
# return failure(newCborError("Extra fields in map"))
|
||||
# else:
|
||||
# return failure(newCborError("Unsupported type: " & $T))
|
||||
# except CatchableError as e:
|
||||
# return failure newCborError(e.msg)
|
||||
# except Exception as e:
|
||||
# raise newException(Defect, e.msg, e)
|
||||
|
||||
proc fromCbor*[T: ref](_: type T, n: CborNode): ?!T =
|
||||
when T is ref:
|
||||
if n.isNull:
|
||||
|
||||
@ -58,20 +58,20 @@ proc writeInitial[T: SomeInteger](str: Stream, m: uint8, n: T): ?!void =
|
||||
str.write(n.uint8)
|
||||
elif uint64(n) <= uint64(uint16.high):
|
||||
str.write(m or 25'u8)
|
||||
str.write((uint8) n shr 8)
|
||||
str.write((uint8) n)
|
||||
str.write((uint8)n shr 8)
|
||||
str.write((uint8)n)
|
||||
elif uint64(n) <= uint64(uint32.high):
|
||||
str.write(m or 26'u8)
|
||||
for i in countdown(24, 8, 8):
|
||||
{.unroll.}
|
||||
str.write((uint8) n shr i)
|
||||
str.write((uint8) n)
|
||||
str.write((uint8)n shr i)
|
||||
str.write((uint8)n)
|
||||
else:
|
||||
str.write(m or 27'u8)
|
||||
for i in countdown(56, 8, 8):
|
||||
{.unroll.}
|
||||
str.write((uint8) n shr i)
|
||||
str.write((uint8) n)
|
||||
str.write((uint8)n shr i)
|
||||
str.write((uint8)n)
|
||||
success()
|
||||
except IOError as e:
|
||||
return failure(e.msg)
|
||||
@ -198,20 +198,20 @@ proc writeCbor*[T: SomeFloat](str: Stream, v: T): ?!void =
|
||||
return success()
|
||||
of fcZero:
|
||||
str.write initialByte(7, 25)
|
||||
str.write((char) 0x00)
|
||||
str.write((char)0x00)
|
||||
of fcNegZero:
|
||||
str.write initialByte(7, 25)
|
||||
str.write((char) 0x80)
|
||||
str.write((char)0x80)
|
||||
of fcInf:
|
||||
str.write initialByte(7, 25)
|
||||
str.write((char) 0x7c)
|
||||
str.write((char)0x7c)
|
||||
of fcNan:
|
||||
str.write initialByte(7, 25)
|
||||
str.write((char) 0x7e)
|
||||
str.write((char)0x7e)
|
||||
of fcNegInf:
|
||||
str.write initialByte(7, 25)
|
||||
str.write((char) 0xfc)
|
||||
str.write((char) 0x00)
|
||||
str.write((char)0xfc)
|
||||
str.write((char)0x00)
|
||||
success()
|
||||
except IOError as io:
|
||||
return failure(io.msg)
|
||||
@ -273,16 +273,16 @@ proc writeCbor*[T: object](str: Stream, v: T): ?!void =
|
||||
?str.writeCbor(f)
|
||||
success()
|
||||
|
||||
proc writeCborArray*(str: Stream, args: varargs[CborNode, toCbor]): ?!void =
|
||||
proc writeCborArray*(str: Stream, args: varargs[CborNode, toCborNode]): ?!void =
|
||||
## Encode to a CBOR array in binary form. This magic doesn't
|
||||
## always work, some arguments may need to be explicitly
|
||||
## converted with ``toCbor`` before passing.
|
||||
## converted with ``toCborNode`` before passing.
|
||||
?str.writeCborArrayLen(args.len)
|
||||
for x in args:
|
||||
?str.writeCbor(x)
|
||||
success()
|
||||
|
||||
proc encode*[T](v: T): ?!string =
|
||||
proc toCbor*[T](v: T): ?!string =
|
||||
## Encode an arbitrary value to CBOR binary representation.
|
||||
## A wrapper over ``writeCbor``.
|
||||
let s = newStringStream()
|
||||
@ -296,7 +296,7 @@ proc toRaw*(n: CborNode): ?!CborNode =
|
||||
if n.kind == cborRaw:
|
||||
return success(n)
|
||||
else:
|
||||
without res =? encode(n), error:
|
||||
without res =? toCbor(n), error:
|
||||
return failure(error)
|
||||
return success(CborNode(kind: cborRaw, raw: res))
|
||||
|
||||
@ -345,25 +345,25 @@ proc writeCbor*(str: Stream, t: Time): ?!void =
|
||||
?writeCbor(str, t.toUnix)
|
||||
success()
|
||||
|
||||
func toCbor*(x: CborNode): ?!CborNode =
|
||||
func toCborNode*(x: CborNode): ?!CborNode =
|
||||
success(x)
|
||||
|
||||
func toCbor*(x: SomeInteger): ?!CborNode =
|
||||
func toCborNode*(x: SomeInteger): ?!CborNode =
|
||||
if x > 0:
|
||||
success(CborNode(kind: cborUnsigned, uint: x.uint64))
|
||||
else:
|
||||
success(CborNode(kind: cborNegative, int: x.int64))
|
||||
|
||||
func toCbor*(x: openArray[byte]): ?!CborNode =
|
||||
func toCborNode*(x: openArray[byte]): ?!CborNode =
|
||||
success(CborNode(kind: cborBytes, bytes: @x))
|
||||
|
||||
func toCbor*(x: string): ?!CborNode =
|
||||
func toCborNode*(x: string): ?!CborNode =
|
||||
success(CborNode(kind: cborText, text: x))
|
||||
|
||||
func toCbor*(x: openArray[CborNode]): ?!CborNode =
|
||||
func toCborNode*(x: openArray[CborNode]): ?!CborNode =
|
||||
success(CborNode(kind: cborArray, seq: @x))
|
||||
|
||||
func toCbor*(pairs: openArray[(CborNode, CborNode)]): ?!CborNode =
|
||||
func toCborNode*(pairs: openArray[(CborNode, CborNode)]): ?!CborNode =
|
||||
try:
|
||||
return success(CborNode(kind: cborMap, map: pairs.toOrderedTable))
|
||||
except CatchableError as e:
|
||||
@ -371,24 +371,24 @@ func toCbor*(pairs: openArray[(CborNode, CborNode)]): ?!CborNode =
|
||||
except Exception as e:
|
||||
raise newException(Defect, e.msg, e)
|
||||
|
||||
func toCbor*(tag: uint64, val: CborNode): ?!CborNode =
|
||||
without res =? toCbor(val), error:
|
||||
func toCborNode*(tag: uint64, val: CborNode): ?!CborNode =
|
||||
without res =? toCborNode(val), error:
|
||||
return failure(error.msg)
|
||||
var cnode = res
|
||||
cnode.tag = some(tag)
|
||||
return success(cnode)
|
||||
|
||||
func toCbor*(x: bool): ?!CborNode =
|
||||
func toCborNode*(x: bool): ?!CborNode =
|
||||
case x
|
||||
of false:
|
||||
success(CborNode(kind: cborSimple, simple: 20))
|
||||
of true:
|
||||
success(CborNode(kind: cborSimple, simple: 21))
|
||||
|
||||
func toCbor*(x: SomeFloat): ?!CborNode =
|
||||
func toCborNode*(x: SomeFloat): ?!CborNode =
|
||||
success(CborNode(kind: cborFloat, float: x.float64))
|
||||
|
||||
func toCbor*(x: pointer): ?!CborNode =
|
||||
func toCborNode*(x: pointer): ?!CborNode =
|
||||
## A hack to produce a CBOR null item.
|
||||
if not x.isNil:
|
||||
return failure("pointer is not nil")
|
||||
@ -398,7 +398,7 @@ func initCborBytes*[T: char | byte](buf: openArray[T]): CborNode =
|
||||
## Create a CBOR byte string from `buf`.
|
||||
result = CborNode(kind: cborBytes, bytes: newSeq[byte](buf.len))
|
||||
for i in 0 ..< buf.len:
|
||||
result.bytes[i] = (byte) buf[i]
|
||||
result.bytes[i] = (byte)buf[i]
|
||||
|
||||
func initCborBytes*(len: int): CborNode =
|
||||
## Create a CBOR byte string of ``len`` bytes.
|
||||
@ -421,6 +421,6 @@ func initCborMap*(initialSize = tables.defaultInitialSize): CborNode =
|
||||
## Initialize a CBOR map.
|
||||
CborNode(kind: cborMap, map: initOrderedTable[CborNode, CborNode](initialSize))
|
||||
|
||||
func initCbor*(items: varargs[CborNode, toCbor]): CborNode =
|
||||
func initCbor*(items: varargs[CborNode, toCborNode]): CborNode =
|
||||
## Initialize a CBOR arrary.
|
||||
CborNode(kind: cborArray, seq: @items)
|
||||
|
||||
@ -13,14 +13,14 @@ type Inner {.serialize.} = object
|
||||
size: uint64
|
||||
|
||||
type CustomPoint {.serialize.} = object
|
||||
u: uint64 # Unsigned integer
|
||||
n: int # Signed integer
|
||||
b: seq[byte] # Byte sequence
|
||||
t: string # Text string
|
||||
arr: seq[int] # Integer sequence
|
||||
tag: float # Floating point
|
||||
flag: bool # Boolean
|
||||
inner: Inner # Nested object
|
||||
u: uint64 # Unsigned integer
|
||||
n: int # Signed integer
|
||||
b: seq[byte] # Byte sequence
|
||||
t: string # Text string
|
||||
arr: seq[int] # Integer sequence
|
||||
tag: float # Floating point
|
||||
flag: bool # Boolean
|
||||
inner: Inner # Nested object
|
||||
innerArr: seq[Inner] # Sequence of objects
|
||||
|
||||
proc generateCustomPoint(): CustomPoint =
|
||||
@ -49,7 +49,7 @@ proc benchmark(): void =
|
||||
|
||||
let cborStartTime = cpuTime()
|
||||
for i in 1 .. 100000:
|
||||
cborStr = encode(point).tryValue
|
||||
cborStr = toCbor(point).tryValue
|
||||
let cborEndTime = cpuTime()
|
||||
let cborDuration = cborEndTime - cborStartTime
|
||||
|
||||
|
||||
@ -48,22 +48,22 @@ type
|
||||
|
||||
# Complex object with various field types to test comprehensive serialization
|
||||
CompositeNested = object
|
||||
u: uint64 # Unsigned integer
|
||||
n: int # Signed integer
|
||||
b: seq[byte] # Byte sequence
|
||||
t: string # Text string
|
||||
arr: seq[int] # Integer sequence
|
||||
tag: float # Floating point
|
||||
flag: bool # Boolean
|
||||
inner: Inner # Nested object
|
||||
innerArr: seq[Inner] # Sequence of objects
|
||||
u: uint64 # Unsigned integer
|
||||
n: int # Signed integer
|
||||
b: seq[byte] # Byte sequence
|
||||
t: string # Text string
|
||||
arr: seq[int] # Integer sequence
|
||||
tag: float # Floating point
|
||||
flag: bool # Boolean
|
||||
inner: Inner # Nested object
|
||||
innerArr: seq[Inner] # Sequence of objects
|
||||
coordinates: tuple[x: int, y: int, label: string] # Tuple
|
||||
refInner: ref Inner # Reference to object
|
||||
refNewInner: NewType # Custom reference type
|
||||
refNil: ref Inner # Nil reference
|
||||
customPoint: CustomPoint # Custom type
|
||||
time: Time # Time
|
||||
date: DateTime # DateTime
|
||||
refInner: ref Inner # Reference to object
|
||||
refNewInner: NewType # Custom reference type
|
||||
refNil: ref Inner # Nil reference
|
||||
customPoint: CustomPoint # Custom type
|
||||
time: Time # Time
|
||||
date: DateTime # DateTime
|
||||
|
||||
# Custom deserialization for CustomColor enum
|
||||
# Converts a CBOR negative integer to a CustomColor enum value
|
||||
@ -107,7 +107,8 @@ proc createPointCbor(x, y: int): CborNode =
|
||||
]
|
||||
|
||||
# Creates a CBOR map node representing a CustomObject
|
||||
proc createObjectCbor(name: string, point: CustomPoint, color: CustomColor): CborNode =
|
||||
proc createObjectCbor(name: string, point: CustomPoint,
|
||||
color: CustomColor): CborNode =
|
||||
result = CborNode(kind: cborMap)
|
||||
result.map = initOrderedTable[CborNode, CborNode]()
|
||||
|
||||
@ -156,29 +157,29 @@ suite "CBOR deserialization":
|
||||
|
||||
# 2. Create a complex object with all supported types
|
||||
var original = CompositeNested(
|
||||
u: 42, # unsigned integer
|
||||
n: -99, # signed integer
|
||||
b: @[byte 1, byte 2], # byte array
|
||||
t: "hi", # string
|
||||
arr: @[1, 2, 3], # integer array
|
||||
tag: 1.5, # float
|
||||
flag: true, # boolean
|
||||
inner: Inner(s: "inner!", nums: @[10, 20]), # nested object
|
||||
u: 42, # unsigned integer
|
||||
n: -99, # signed integer
|
||||
b: @[byte 1, byte 2], # byte array
|
||||
t: "hi", # string
|
||||
arr: @[1, 2, 3], # integer array
|
||||
tag: 1.5, # float
|
||||
flag: true, # boolean
|
||||
inner: Inner(s: "inner!", nums: @[10, 20]), # nested object
|
||||
innerArr:
|
||||
@[ # array of objects
|
||||
@[ # array of objects
|
||||
Inner(s: "first", nums: @[1, 2]), Inner(s: "second", nums: @[3, 4, 5])
|
||||
],
|
||||
coordinates: (x: 10, y: 20, label: "test"), # tuple
|
||||
refInner: refInner, # reference to object
|
||||
refNewInner: refNewObj, # custom reference type
|
||||
refNil: nil, # nil reference
|
||||
customPoint: CustomPoint(x: 15, y: 25), # custom type
|
||||
time: getTime(), # time
|
||||
date: now().utc, # date
|
||||
coordinates: (x: 10, y: 20, label: "test"), # tuple
|
||||
refInner: refInner, # reference to object
|
||||
refNewInner: refNewObj, # custom reference type
|
||||
refNil: nil, # nil reference
|
||||
customPoint: CustomPoint(x: 15, y: 25), # custom type
|
||||
time: getTime(), # time
|
||||
date: now().utc, # date
|
||||
)
|
||||
|
||||
# Test serialization using encode helper
|
||||
without encodedStr =? encode(original), error:
|
||||
without encodedStr =? toCbor(original), error:
|
||||
fail()
|
||||
|
||||
# Test serialization using stream API
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user