use crate::field_number::FieldNumber;
use ::std::convert::TryFrom;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum WireType {
Varint = 0,
Int64 = 1,
Len = 2,
SGroup = 3,
EGroup = 4,
Int32 = 5,
}
impl From<WireType> for u8 {
#[inline]
fn from(wire_type: WireType) -> Self {
wire_type as u8
}
}
impl TryFrom<u8> for WireType {
type Error = crate::ProtobufError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(WireType::Varint),
1 => Ok(WireType::Int64),
2 => Ok(WireType::Len),
3 => Ok(WireType::SGroup),
4 => Ok(WireType::EGroup),
5 => Ok(WireType::Int32),
_ => Err(crate::ProtobufError::InvalidWireType { value }),
}
}
}
pub const MAX_FIELD_NUMBER: FieldNumber = FieldNumber::MAX;
pub const MIN_FIELD_NUMBER: FieldNumber = FieldNumber::MIN;
pub const MAX_MESSAGE_SIZE: usize = 2 * 1024 * 1024 * 1024;
pub const MAX_STRING_SIZE: usize = 2 * 1024 * 1024 * 1024;
pub const WIRE_TYPE_MASK: u32 = 0b111;
pub const FIELD_NUMBER_SHIFT: u32 = 3;
pub const MAX_VARINT_BYTES: usize = 10;
pub const MAX_9_BYTE_VARINT: u64 = 0x7FFF_FFFF_FFFF_FFFF;
pub const MAX_8_BYTE_VARINT: u64 = 0xFF_FFFF_FFFF_FFFF;
pub const MAX_7_BYTE_VARINT: u64 = 0x0001_FFFF_FFFF_FFFF;
pub const MAX_6_BYTE_VARINT: u64 = 0x3FF_FFFF_FFFF;
pub const MAX_5_BYTE_VARINT: u64 = 0x7_FFFF_FFFF;
pub const MAX_4_BYTE_VARINT: u64 = 0xFFF_FFFF;
pub const MAX_3_BYTE_VARINT: u64 = 0x1F_FFFF;
pub const MAX_2_BYTE_VARINT: u64 = 0x3FFF;
pub const MAX_1_BYTE_VARINT: u64 = 0x7F;
pub const VARINT_CONTINUATION_BIT: u8 = 0x80;
pub const VARINT_PAYLOAD_MASK: u8 = 0x7F;
pub const FIXED32_BYTES: usize = 4;
pub const FIXED64_BYTES: usize = 8;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wire_type_try_from_trait() {
assert_eq!(WireType::try_from(0).unwrap(), WireType::Varint);
assert_eq!(WireType::try_from(1).unwrap(), WireType::Int64);
assert_eq!(WireType::try_from(2).unwrap(), WireType::Len);
assert_eq!(WireType::try_from(3).unwrap(), WireType::SGroup);
assert_eq!(WireType::try_from(4).unwrap(), WireType::EGroup);
assert_eq!(WireType::try_from(5).unwrap(), WireType::Int32);
let result = WireType::try_from(6);
assert!(result.is_err());
if let Err(crate::ProtobufError::InvalidWireType { value }) = result {
assert_eq!(value, 6);
} else {
panic!("Expected InvalidWireType error");
}
let result = WireType::try_from(255);
assert!(result.is_err());
if let Err(crate::ProtobufError::InvalidWireType { value }) = result {
assert_eq!(value, 255);
} else {
panic!("Expected InvalidWireType error");
}
}
#[test]
fn test_varint_size_constants_mathematical() {
let constants = [
MAX_1_BYTE_VARINT,
MAX_2_BYTE_VARINT,
MAX_3_BYTE_VARINT,
MAX_4_BYTE_VARINT,
MAX_5_BYTE_VARINT,
MAX_6_BYTE_VARINT,
MAX_7_BYTE_VARINT,
MAX_8_BYTE_VARINT,
MAX_9_BYTE_VARINT,
];
for (i, &constant) in constants.iter().enumerate() {
let expected_bits = (i + 1) * 7;
let expected_value = (1u64 << expected_bits) - 1;
assert_eq!(
constant,
expected_value,
"MAX_{}_BYTE_VARINT should be 2^{} - 1 = {}",
i + 1,
expected_bits,
expected_value
);
}
}
}