diff --git a/serde/cbor/deserializer.nim b/serde/cbor/deserializer.nim index 3d406f9..3d08e41 100644 --- a/serde/cbor/deserializer.nim +++ b/serde/cbor/deserializer.nim @@ -88,9 +88,9 @@ proc nextUInt*(c: var CborParser): ?!BiggestUInt = if c.kind != CborEventKind.cborPositive: return failure(newCborError("Expected positive integer, got " & $c.kind)) let val = c.intVal.BiggestUInt - let nextRes = c.next() - if nextRes.isFailure: - return failure(nextRes.error) + + ?c.next() + return success(val) @@ -105,9 +105,7 @@ proc nextInt*(c: var CborParser): ?!BiggestInt = else: return failure(newCborError("Expected integer, got " & $c.kind)) - let nextRes = c.next() - if nextRes.isFailure: - return failure(nextRes.error) + ?c.next() return success(val) @@ -126,9 +124,7 @@ proc nextFloat*(c: var CborParser): ?!float64 = else: discard - let nextRes = c.next() - if nextRes.isFailure: - return failure(nextRes.error) + ?c.next() return success(val) @@ -498,31 +494,31 @@ proc parseTime(n: CborNode): Time = else: assert false -proc fromCborHook*(v: var DateTime; n: CborNode): bool = +proc fromCborHook*(v: var DateTime; n: CborNode): ?!void = ## Parse a `DateTime` from the tagged string representation ## defined in RCF7049 section 2.4.1. if n.tag.isSome: try: if n.tag.get == 0 and n.kind == cborText: v = parseDateText(n) - result = true + return success() elif n.tag.get == 1 and n.kind in {cborUnsigned, cborNegative, cborFloat}: v = parseTime(n).utc - result = true - except ValueError: discard + return success() + except ValueError as e: return failure(e) -proc fromCborHook*(v: var Time; n: CborNode): bool = +proc fromCborHook*(v: var Time; n: CborNode): ?!void = ## Parse a `Time` from the tagged string representation ## defined in RCF7049 section 2.4.1. if n.tag.isSome: try: if n.tag.get == 0 and n.kind == cborText: v = parseDateText(n).toTime - result = true + return success() elif n.tag.get == 1 and n.kind in {cborUnsigned, cborNegative, cborFloat}: v = parseTime(n) - result = true - except ValueError: discard + return success() + except ValueError as e: return failure(e) func isTagged*(n: CborNode): bool = ## Check if a CBOR item has a tag. diff --git a/serde/cbor/serializer.nim b/serde/cbor/serializer.nim index 4165547..294b2ce 100644 --- a/serde/cbor/serializer.nim +++ b/serde/cbor/serializer.nim @@ -119,7 +119,7 @@ proc writeCbor*[T](str: Stream; v: T): ?!void = try: when T is CborNode: if v.tag.isSome: - return str.writeCborTag(v.tag.get) + ?str.writeCborTag(v.tag.get) case v.kind: of cborUnsigned: return str.writeCbor(v.uint) @@ -158,7 +158,7 @@ proc writeCbor*[T](str: Stream; v: T): ?!void = of cborRaw: str.write(v.raw) elif compiles(writeCborHook(str, v)): - writeCborHook(str, v) + ?writeCborHook(str, v) elif T is SomeUnsignedInt: ?str.writeInitial(0, v) elif T is SomeSignedInt: @@ -231,7 +231,6 @@ proc writeCbor*[T](str: Stream; v: T): ?!void = var be: float64 swapEndian64 be.addr, v.unsafeAddr str.write be - return success() of fcZero: str.write initialByte(7, 25) @@ -262,6 +261,7 @@ proc writeCborArray*(str: Stream; args: varargs[CborNode, toCbor]): ?!void = ?str.writeCborArrayLen(args.len) for x in args: ?str.writeCbor(x) + success() proc encode*[T](v: T): ?!string = ## Encode an arbitrary value to CBOR binary representation. @@ -313,12 +313,14 @@ proc writeCborHook*(str: Stream; dt: DateTime): ?!void = ## defined in RCF7049 section 2.4.1. ?writeCborTag(str, 0) ?writeCbor(str, format(dt, timeFormat)) + success() proc writeCborHook*(str: Stream; t: Time): ?!void = ## Write a `Time` using the tagged numerical representation ## defined in RCF7049 section 2.4.1. ?writeCborTag(str, 1) ?writeCbor(str, t.toUnix) + success() func toCbor*(x: CborNode): ?!CborNode = success(x) diff --git a/tests/cbor/testprimitives.nim b/tests/cbor/testprimitives.nim index 0cf988c..a3e4ae7 100644 --- a/tests/cbor/testprimitives.nim +++ b/tests/cbor/testprimitives.nim @@ -54,7 +54,8 @@ suite "roundtrip": without c =? parseCbor(controlCbor), error: fail() test name: - let testCbor = encode(c) + without testCbor =? encode(c), error: + fail() if controlCbor != testCbor: let testB64 = base64.encode(testCbor) check(controlB64 == testB64) @@ -62,42 +63,44 @@ suite "roundtrip": suite "hooks": test "DateTime": let dt = now() - var - bin = encode(dt) + + without bin =? encode(dt), error: + fail() without node =? parseCbor(bin), error: fail() check(node.text == $dt) test "Time": let t = now().toTime var - bin = encode(t) + bin = encode(t).tryValue without node =? parseCbor(bin), error: fail() check(node.getInt == t.toUnix) test "tag": - var c = toCbor("foo") + var c = toCbor("foo").tryValue c.tag = some(99'u64) check c.tag == some(99'u64) test "sorting": var map = initCborMap() var keys = @[ - toCbor(10), - toCbor(100), - toCbor(-1), - toCbor("z"), - toCbor("aa"), - toCbor([toCbor(100)]), - toCbor([toCbor(-1)]), - toCbor(false), + toCbor(10).tryValue, + toCbor(100).tryValue, + toCbor(-1).tryValue, + toCbor("z").tryValue, + toCbor("aa").tryValue, + toCbor([toCbor(100).tryValue]).tryValue, + toCbor([toCbor(-1).tryValue]).tryValue, + toCbor(false).tryValue, ] shuffle(keys) - for k in keys: map[k] = toCbor(0) - check not map.isSorted - sort(map) - check map.isSorted + for k in keys: map[k] = toCbor(0).tryValue + + check not map.isSorted.tryValue + check sort(map).isSuccess + check map.isSorted.tryValue test "invalid wire type": var intValue: int