///|
/// Protobuf wire type numbers as defined by the encoding specification.
pub(all) enum WireType {
Varint
Fixed64
LengthDelimited
StartGroup
EndGroup
Fixed32
} derive(Debug, Eq)
///|
/// Numeric tag used in the low three bits of a protobuf key.
pub fn WireType::number(self : WireType) -> Int {
match self {
Varint => 0
Fixed64 => 1
LengthDelimited => 2
StartGroup => 3
EndGroup => 4
Fixed32 => 5
}
}
///|
/// Convert a raw wire type number to a typed value.
pub fn wire_type_from_number(n : Int) -> WireType? {
match n {
0 => Some(Varint)
1 => Some(Fixed64)
2 => Some(LengthDelimited)
3 => Some(StartGroup)
4 => Some(EndGroup)
5 => Some(Fixed32)
_ => None
}
}
///|
/// Build a protobuf key: `(field_number << 3) | wire_type`.
pub fn make_key(field_number : Int, wire : WireType) -> UInt64 {
(field_number.to_uint64() << 3) | wire.number().to_uint64()
}
///|
/// Result of splitting a protobuf key into field number and wire type.
pub(all) enum ParseKeyResult {
KeyOk(Int, WireType)
KeyErr(DecodeError)
} derive(Debug, Eq)
///|
/// Parse a raw protobuf key varint value.
pub fn parse_key(raw : UInt64) -> ParseKeyResult {
let field_number = (raw >> 3).to_int()
let wire_num = (raw & 7UL).to_int()
if field_number <= 0 {
KeyErr(InvalidFieldNumber(field_number))
} else {
match wire_type_from_number(wire_num) {
Some(w) => KeyOk(field_number, w)
None => KeyErr(InvalidWireType(wire_num))
}
}
}
///|
/// Encode a key as a protobuf varint.
pub fn encode_key(field_number : Int, wire : WireType) -> Bytes {
encode_varint_u64(make_key(field_number, wire))
}