From 0e2fd5c22d77026edc27cfc279af616c54225bc3 Mon Sep 17 00:00:00 2001 From: munna0908 Date: Sat, 31 May 2025 17:57:34 +0530 Subject: [PATCH] refactor: rename encode to toCbor and toCbor to toCborNode for consistency --- serde/cbor/deserializer.nim | 99 ------------------------------------- serde/cbor/serializer.nim | 58 +++++++++++----------- tests/benchmark.nim | 18 +++---- tests/cbor/testObjects.nim | 67 ++++++++++++------------- 4 files changed, 72 insertions(+), 170 deletions(-) diff --git a/serde/cbor/deserializer.nim b/serde/cbor/deserializer.nim index 6007104..40fa119 100644 --- a/serde/cbor/deserializer.nim +++ b/serde/cbor/deserializer.nim @@ -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: diff --git a/serde/cbor/serializer.nim b/serde/cbor/serializer.nim index a222f0d..ea0c241 100644 --- a/serde/cbor/serializer.nim +++ b/serde/cbor/serializer.nim @@ -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) diff --git a/tests/benchmark.nim b/tests/benchmark.nim index 32f83c5..9be16b2 100644 --- a/tests/benchmark.nim +++ b/tests/benchmark.nim @@ -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 diff --git a/tests/cbor/testObjects.nim b/tests/cbor/testObjects.nim index 20be59a..53bcc71 100644 --- a/tests/cbor/testObjects.nim +++ b/tests/cbor/testObjects.nim @@ -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