nwaku/waku/common/protobuf.nim

94 lines
2.2 KiB
Nim
Raw Normal View History

# Extensions for libp2p's protobuf library implementation
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
std/options,
libp2p/protobuf/minprotobuf,
libp2p/varint
export
minprotobuf,
varint
## Custom errors
type
ProtobufErrorKind* {.pure.} = enum
DecodeFailure
MissingRequiredField
InvalidLengthField
ProtobufError* = object
case kind*: ProtobufErrorKind
of DecodeFailure:
error*: minprotobuf.ProtoError
of MissingRequiredField, InvalidLengthField:
field*: string
ProtobufResult*[T] = Result[T, ProtobufError]
converter toProtobufError*(err: minprotobuf.ProtoError): ProtobufError =
case err:
of minprotobuf.ProtoError.RequiredFieldMissing:
ProtobufError(kind: ProtobufErrorKind.MissingRequiredField, field: "unknown")
else:
ProtobufError(kind: ProtobufErrorKind.DecodeFailure, error: err)
proc missingRequiredField*(T: type ProtobufError, field: string): T =
ProtobufError(kind: ProtobufErrorKind.MissingRequiredField, field: field)
proc invalidLengthField*(T: type ProtobufError, field: string): T =
ProtobufError(kind: ProtobufErrorKind.InvalidLengthField, field: field)
## Extension methods
proc write3*(proto: var ProtoBuffer, field: int, value: auto) =
when value is Option:
if value.isSome():
proto.write(field, value.get())
elif value is bool:
proto.write(field, zint(value))
else:
proto.write(field, value)
proc finish3*(proto: var ProtoBuffer) =
if proto.buffer.len > 0:
proto.finish()
else:
proto.offset = 0
proc `==`*(a: zint64, b: zint64): bool =
int64(a) == int64(b)
proc `$`*(err: ProtobufError): string =
case err.kind:
of DecodeFailure:
case err.error:
of VarintDecode:
return "VarintDecode"
of MessageIncomplete:
return "MessageIncomplete"
of BufferOverflow:
return "BufferOverflow"
of MessageTooBig:
return "MessageTooBig"
of BadWireType:
return "BadWireType"
of IncorrectBlob:
return "IncorrectBlob"
of RequiredFieldMissing:
return "RequiredFieldMissing"
of MissingRequiredField:
return "MissingRequiredField " & err.field
of InvalidLengthField:
return "InvalidLengthField " & err.field