use crate::field_number::FieldNumber;
use crate::tag::Tag;
use crate::varint::Varint;
use crate::wire_format::WireType;
#[cfg(feature = "read")]
pub(crate) mod read;
#[cfg(feature = "write")]
pub(crate) mod write;
#[cfg(feature = "read")]
pub use self::read::{
AsRefExtProtobuf, IteratorExtProtobuf, ProtobufFieldIterator, ProtobufFieldIteratorFromBytes,
ProtobufFieldSliceIterator, ReadExtProtobuf, TryIteratorExtProtobuf,
};
#[cfg(feature = "write")]
pub use self::write::WriteExtProtobuf;
#[derive(Debug, Clone, PartialEq)]
pub enum FieldValue<L> {
Varint(Varint),
I32([u8; 4]),
I64([u8; 8]),
Len(L),
}
impl<L> FieldValue<L> {
pub fn from_varint(varint: Varint) -> Self {
Self::Varint(varint)
}
pub fn from_uint64(value: u64) -> Self {
Self::Varint(Varint::from_uint64(value))
}
pub fn from_uint32(value: u32) -> Self {
Self::Varint(Varint::from_uint32(value))
}
pub fn from_sint64(value: i64) -> Self {
Self::Varint(Varint::from_sint64(value))
}
pub fn from_sint32(value: i32) -> Self {
Self::Varint(Varint::from_sint32(value))
}
pub fn from_int64(value: i64) -> Self {
Self::Varint(Varint::from_int64(value))
}
pub fn from_int32(value: i32) -> Self {
Self::Varint(Varint::from_int32(value))
}
pub fn from_bool(value: bool) -> Self {
Self::Varint(Varint::from_bool(value))
}
pub fn from_fixed32(value: u32) -> Self {
Self::I32(value.to_le_bytes())
}
pub fn from_sfixed32(value: i32) -> Self {
Self::I32(value.to_le_bytes())
}
pub fn from_float(value: f32) -> Self {
Self::I32(value.to_le_bytes())
}
pub fn from_fixed64(value: u64) -> Self {
Self::I64(value.to_le_bytes())
}
pub fn from_sfixed64(value: i64) -> Self {
Self::I64(value.to_le_bytes())
}
pub fn from_double(value: f64) -> Self {
Self::I64(value.to_le_bytes())
}
pub fn encoded_size(&self) -> usize
where
L: AsRef<[u8]>,
{
match self {
Self::Varint(varint) => varint.varint_size(),
Self::I32(_) => 4,
Self::I64(_) => 8,
Self::Len(data) => {
let data_slice = data.as_ref();
let length = data_slice.len() as u64;
let length_varint = Varint::from_uint64(length);
length_varint.varint_size() + data_slice.len()
}
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Field<L> {
pub field_number: FieldNumber,
pub value: FieldValue<L>,
}
impl<L> Field<L> {
pub fn new(field_number: FieldNumber, value: FieldValue<L>) -> Self {
Self {
field_number,
value,
}
}
pub fn encoded_size(&self) -> usize
where
L: AsRef<[u8]>,
{
let wire_type = match &self.value {
FieldValue::Varint(_) => WireType::Varint,
FieldValue::I32(_) => WireType::Int32,
FieldValue::I64(_) => WireType::Int64,
FieldValue::Len(_) => WireType::Len,
};
let tag = Tag {
field_number: self.field_number,
wire_type,
};
let tag_varint = tag.to_encoded();
let tag_size = tag_varint.varint_size();
let value_size = self.value.encoded_size();
tag_size + value_size
}
}