refactor: rename encode to toCbor and toCbor to toCborNode for consistency

This commit is contained in:
munna0908 2025-05-31 17:57:34 +05:30
parent 9d3da40c0a
commit 0e2fd5c22d
No known key found for this signature in database
GPG Key ID: 2FFCD637E937D3E6
4 changed files with 72 additions and 170 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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