#![doc(hidden)]
use std::marker;
#[cfg(feature = "bytes")]
use ::bytes::Bytes;
#[cfg(feature = "bytes")]
use crate::chars::Chars;
use crate::coded_input_stream::CodedInputStream;
use crate::coded_output_stream::CodedOutputStream;
use crate::enums::Enum;
use crate::error::Result;
pub use crate::reflect::type_dynamic::ProtobufTypeDynamic;
use crate::reflect::type_dynamic::ProtobufTypeDynamicImpl;
use crate::reflect::ProtobufValue;
use crate::rt;
use crate::rt::singular::value_varint_zigzag_size_no_tag;
use crate::wire_format::WireType;
use crate::zigzag::decode_zig_zag_32;
use crate::zigzag::decode_zig_zag_64;
use crate::EnumOrUnknown;
use crate::Message;
use crate::UnknownValueRef;
pub(crate) trait ProtobufTypeTrait: Send + Sync + Clone + Sized + 'static {
type ProtobufValue: Default;
fn dynamic() -> &'static dyn ProtobufTypeDynamic
where
Self::ProtobufValue: ProtobufValue,
{
&ProtobufTypeDynamicImpl::<Self>(marker::PhantomData)
}
const WIRE_TYPE: WireType;
fn read(is: &mut CodedInputStream) -> Result<Self::ProtobufValue>;
fn get_from_unknown(_unknown: UnknownValueRef) -> Option<Self::ProtobufValue>;
fn compute_size(value: &Self::ProtobufValue) -> u64;
fn compute_size_with_length_delimiter(value: &Self::ProtobufValue) -> u64 {
let size = Self::compute_size(value);
if Self::WIRE_TYPE == WireType::LengthDelimited {
rt::compute_raw_varint64_size(size) + size
} else {
size
}
}
#[inline]
fn get_cached_size(value: &Self::ProtobufValue) -> u32 {
Self::compute_size(value) as u32
}
#[inline]
fn get_cached_size_with_length_delimiter(value: &Self::ProtobufValue) -> u32 {
let size = Self::get_cached_size(value);
if Self::WIRE_TYPE == WireType::LengthDelimited {
rt::compute_raw_varint32_size(size) as u32 + size
} else {
size
}
}
fn write_with_cached_size(
field_number: u32,
value: &Self::ProtobufValue,
os: &mut CodedOutputStream,
) -> Result<()>;
}
pub(crate) trait ProtobufTypeFixed: ProtobufTypeTrait {
const ENCODED_SIZE: u32;
}
#[derive(Copy, Clone)]
pub struct ProtobufTypeFloat;
#[derive(Copy, Clone)]
pub struct ProtobufTypeDouble;
#[derive(Copy, Clone)]
pub struct ProtobufTypeInt32;
#[derive(Copy, Clone)]
pub struct ProtobufTypeInt64;
#[derive(Copy, Clone)]
pub struct ProtobufTypeUint32;
#[derive(Copy, Clone)]
pub struct ProtobufTypeUint64;
#[derive(Copy, Clone)]
pub struct ProtobufTypeSint32;
#[derive(Copy, Clone)]
pub struct ProtobufTypeSint64;
#[derive(Copy, Clone)]
pub struct ProtobufTypeFixed32;
#[derive(Copy, Clone)]
pub struct ProtobufTypeFixed64;
#[derive(Copy, Clone)]
pub struct ProtobufTypeSfixed32;
#[derive(Copy, Clone)]
pub struct ProtobufTypeSfixed64;
#[derive(Copy, Clone)]
pub struct ProtobufTypeBool;
#[derive(Copy, Clone)]
pub struct ProtobufTypeString;
#[derive(Copy, Clone)]
pub struct ProtobufTypeBytes;
#[cfg(feature = "bytes")]
#[derive(Copy, Clone)]
pub struct ProtobufTypeTokioBytes;
#[cfg(feature = "bytes")]
#[derive(Copy, Clone)]
pub struct ProtobufTypeTokioChars;
#[derive(Copy, Clone)]
pub struct ProtobufTypeEnumOrUnknown<E: Enum>(marker::PhantomData<E>);
#[derive(Copy, Clone)]
pub struct ProtobufTypeMessage<M: Message>(marker::PhantomData<M>);
impl ProtobufTypeTrait for ProtobufTypeFloat {
type ProtobufValue = f32;
const WIRE_TYPE: WireType = WireType::Fixed32;
fn read(is: &mut CodedInputStream) -> Result<f32> {
is.read_float()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<f32> {
match unknown {
UnknownValueRef::Fixed32(v) => Some(f32::from_bits(v)),
_ => None,
}
}
fn compute_size(_value: &f32) -> u64 {
Self::ENCODED_SIZE as u64
}
fn write_with_cached_size(
field_number: u32,
value: &f32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_float(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeFloat {
const ENCODED_SIZE: u32 = 4;
}
impl ProtobufTypeTrait for ProtobufTypeDouble {
type ProtobufValue = f64;
const WIRE_TYPE: WireType = WireType::Fixed64;
fn read(is: &mut CodedInputStream) -> Result<f64> {
is.read_double()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<f64> {
match unknown {
UnknownValueRef::Fixed64(v) => Some(f64::from_bits(v)),
_ => None,
}
}
fn compute_size(_value: &f64) -> u64 {
Self::ENCODED_SIZE as u64
}
fn write_with_cached_size(
field_number: u32,
value: &f64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_double(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeDouble {
const ENCODED_SIZE: u32 = 8;
}
impl ProtobufTypeTrait for ProtobufTypeInt32 {
type ProtobufValue = i32;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<i32> {
is.read_int32()
}
fn compute_size(value: &i32) -> u64 {
if *value < 0 {
return 10;
}
rt::compute_raw_varint32_size(*value as u32)
}
fn write_with_cached_size(
field_number: u32,
value: &i32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_int32(field_number, *value)
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i32> {
match unknown {
UnknownValueRef::Varint(v) => Some(v as i32),
_ => None,
}
}
}
impl ProtobufTypeTrait for ProtobufTypeInt64 {
type ProtobufValue = i64;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<i64> {
is.read_int64()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i64> {
match unknown {
UnknownValueRef::Varint(v) => Some(v as i64),
_ => None,
}
}
fn compute_size(value: &i64) -> u64 {
rt::compute_raw_varint64_size(*value as u64)
}
fn write_with_cached_size(
field_number: u32,
value: &i64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_int64(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeUint32 {
type ProtobufValue = u32;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<u32> {
is.read_uint32()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<u32> {
match unknown {
UnknownValueRef::Varint(v) => Some(v as u32),
_ => None,
}
}
fn compute_size(value: &u32) -> u64 {
rt::compute_raw_varint32_size(*value)
}
fn write_with_cached_size(
field_number: u32,
value: &u32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_uint32(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeUint64 {
type ProtobufValue = u64;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<u64> {
is.read_uint64()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<u64> {
match unknown {
UnknownValueRef::Varint(v) => Some(v as u64),
_ => None,
}
}
fn compute_size(value: &u64) -> u64 {
rt::compute_raw_varint64_size(*value)
}
fn write_with_cached_size(
field_number: u32,
value: &u64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_uint64(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeSint32 {
type ProtobufValue = i32;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<i32> {
is.read_sint32()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i32> {
ProtobufTypeUint32::get_from_unknown(unknown).map(decode_zig_zag_32)
}
fn compute_size(value: &i32) -> u64 {
value_varint_zigzag_size_no_tag(*value)
}
fn write_with_cached_size(
field_number: u32,
value: &i32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_sint32(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeSint64 {
type ProtobufValue = i64;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<i64> {
is.read_sint64()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i64> {
ProtobufTypeUint64::get_from_unknown(unknown).map(decode_zig_zag_64)
}
fn compute_size(value: &i64) -> u64 {
value_varint_zigzag_size_no_tag(*value)
}
fn write_with_cached_size(
field_number: u32,
value: &i64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_sint64(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeFixed32 {
type ProtobufValue = u32;
const WIRE_TYPE: WireType = WireType::Fixed32;
fn read(is: &mut CodedInputStream) -> Result<u32> {
is.read_fixed32()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<u32> {
match unknown {
UnknownValueRef::Fixed32(v) => Some(v),
_ => None,
}
}
fn compute_size(_value: &u32) -> u64 {
Self::ENCODED_SIZE as u64
}
fn write_with_cached_size(
field_number: u32,
value: &u32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_fixed32(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeFixed32 {
const ENCODED_SIZE: u32 = 4;
}
impl ProtobufTypeTrait for ProtobufTypeFixed64 {
type ProtobufValue = u64;
const WIRE_TYPE: WireType = WireType::Fixed64;
fn read(is: &mut CodedInputStream) -> Result<u64> {
is.read_fixed64()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<u64> {
match unknown {
UnknownValueRef::Fixed64(v) => Some(v),
_ => None,
}
}
fn compute_size(_value: &u64) -> u64 {
Self::ENCODED_SIZE as u64
}
fn write_with_cached_size(
field_number: u32,
value: &u64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_fixed64(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeFixed64 {
const ENCODED_SIZE: u32 = 8;
}
impl ProtobufTypeTrait for ProtobufTypeSfixed32 {
type ProtobufValue = i32;
const WIRE_TYPE: WireType = WireType::Fixed32;
fn read(is: &mut CodedInputStream) -> Result<i32> {
is.read_sfixed32()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i32> {
match unknown {
UnknownValueRef::Fixed32(v) => Some(v as i32),
_ => None,
}
}
fn compute_size(_value: &i32) -> u64 {
Self::ENCODED_SIZE as u64
}
fn write_with_cached_size(
field_number: u32,
value: &i32,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_sfixed32(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeSfixed32 {
const ENCODED_SIZE: u32 = 4;
}
impl ProtobufTypeTrait for ProtobufTypeSfixed64 {
type ProtobufValue = i64;
const WIRE_TYPE: WireType = WireType::Fixed64;
fn read(is: &mut CodedInputStream) -> Result<i64> {
is.read_sfixed64()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<i64> {
match unknown {
UnknownValueRef::Fixed64(v) => Some(v as i64),
_ => None,
}
}
fn compute_size(_value: &i64) -> u64 {
8
}
fn write_with_cached_size(
field_number: u32,
value: &i64,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_sfixed64(field_number, *value)
}
}
impl ProtobufTypeFixed for ProtobufTypeSfixed64 {
const ENCODED_SIZE: u32 = 8;
}
impl ProtobufTypeTrait for ProtobufTypeBool {
type ProtobufValue = bool;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<bool> {
is.read_bool()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<bool> {
match unknown {
UnknownValueRef::Varint(b) => Some(b != 0),
_ => None,
}
}
fn compute_size(_value: &bool) -> u64 {
1
}
fn write_with_cached_size(
field_number: u32,
value: &bool,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_bool(field_number, *value)
}
}
impl ProtobufTypeTrait for ProtobufTypeString {
type ProtobufValue = String;
const WIRE_TYPE: WireType = WireType::LengthDelimited;
fn read(is: &mut CodedInputStream) -> Result<String> {
is.read_string()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<String> {
match unknown {
UnknownValueRef::LengthDelimited(v) => String::from_utf8(v.to_vec()).ok(),
_ => None,
}
}
fn compute_size(value: &String) -> u64 {
value.len() as u64
}
fn write_with_cached_size(
field_number: u32,
value: &String,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_string(field_number, &value)
}
}
impl ProtobufTypeTrait for ProtobufTypeBytes {
type ProtobufValue = Vec<u8>;
const WIRE_TYPE: WireType = WireType::LengthDelimited;
fn read(is: &mut CodedInputStream) -> Result<Vec<u8>> {
is.read_bytes()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<Vec<u8>> {
match unknown {
UnknownValueRef::LengthDelimited(v) => Some(v.to_vec()),
_ => None,
}
}
fn compute_size(value: &Vec<u8>) -> u64 {
value.len() as u64
}
fn write_with_cached_size(
field_number: u32,
value: &Vec<u8>,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_bytes(field_number, &value)
}
}
#[cfg(feature = "bytes")]
impl ProtobufTypeTrait for ProtobufTypeTokioBytes {
type ProtobufValue = bytes::Bytes;
const WIRE_TYPE: WireType = ProtobufTypeBytes::WIRE_TYPE;
fn read(is: &mut CodedInputStream) -> Result<Bytes> {
is.read_tokio_bytes()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<Bytes> {
ProtobufTypeBytes::get_from_unknown(unknown).map(Bytes::from)
}
fn compute_size(value: &Bytes) -> u64 {
value.len() as u64
}
fn write_with_cached_size(
field_number: u32,
value: &Bytes,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_bytes(field_number, &value)
}
}
#[cfg(feature = "bytes")]
impl ProtobufTypeTrait for ProtobufTypeTokioChars {
type ProtobufValue = Chars;
const WIRE_TYPE: WireType = ProtobufTypeBytes::WIRE_TYPE;
fn read(is: &mut CodedInputStream) -> Result<Chars> {
is.read_tokio_chars()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<Chars> {
ProtobufTypeString::get_from_unknown(unknown).map(Chars::from)
}
fn compute_size(value: &Chars) -> u64 {
value.len() as u64
}
fn write_with_cached_size(
field_number: u32,
value: &Chars,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_string(field_number, &value)
}
}
impl<E: Enum> ProtobufTypeTrait for ProtobufTypeEnumOrUnknown<E> {
type ProtobufValue = EnumOrUnknown<E>;
const WIRE_TYPE: WireType = WireType::Varint;
fn read(is: &mut CodedInputStream) -> Result<EnumOrUnknown<E>> {
is.read_enum_or_unknown()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<EnumOrUnknown<E>> {
ProtobufTypeInt32::get_from_unknown(unknown).map(|i| EnumOrUnknown::from_i32(i))
}
fn compute_size(value: &EnumOrUnknown<E>) -> u64 {
ProtobufTypeInt32::compute_size(&value.value())
}
fn write_with_cached_size(
field_number: u32,
value: &EnumOrUnknown<E>,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_enum_or_unknown(field_number, *value)
}
}
impl<M: Message + Clone + Default> ProtobufTypeTrait for ProtobufTypeMessage<M> {
type ProtobufValue = M;
const WIRE_TYPE: WireType = WireType::LengthDelimited;
fn read(is: &mut CodedInputStream) -> Result<M> {
is.read_message()
}
fn get_from_unknown(unknown: UnknownValueRef) -> Option<M> {
match unknown {
UnknownValueRef::LengthDelimited(v) => M::parse_from_bytes(&v).ok(),
_ => None,
}
}
fn compute_size(value: &M) -> u64 {
value.compute_size()
}
fn get_cached_size(value: &M) -> u32 {
value.cached_size()
}
fn write_with_cached_size(
field_number: u32,
value: &Self::ProtobufValue,
os: &mut CodedOutputStream,
) -> Result<()> {
os.write_tag(field_number, WireType::LengthDelimited)?;
os.write_raw_varint32(value.cached_size())?;
value.write_to_with_cached_sizes(os)?;
Ok(())
}
}