#[cfg(feature = "chrono")]
mod chrono;
mod wkt;
use prost_types::field_descriptor_proto::Type as ProstFieldType;
#[doc(hidden)]
pub fn prost_file_descriptor_set_to_vec(
file_descriptor_set: &prost_types::FileDescriptorSet,
) -> Vec<u8> {
use prost::Message;
file_descriptor_set.encode_to_vec()
}
#[doc(hidden)]
pub fn encode_varint(value: u64, buf: &mut impl bytes::BufMut) {
prost::encoding::encode_varint(value, buf);
}
#[doc(hidden)]
pub fn encoded_len_varint(value: u64) -> usize {
prost::encoding::encoded_len_varint(value)
}
pub trait ProtobufField {
fn field_type() -> ProstFieldType;
fn wire_type() -> u32;
fn write_tagged(&self, field_number: u32, buf: &mut impl bytes::BufMut) {
let tag = (field_number << 3) | Self::wire_type();
prost::encoding::encode_varint(tag as u64, buf);
self.write(buf);
}
fn write(&self, buf: &mut impl bytes::BufMut);
fn type_name() -> Option<String> {
None
}
fn enum_descriptor() -> Option<prost_types::EnumDescriptorProto> {
None
}
fn message_descriptor() -> Option<prost_types::DescriptorProto> {
None
}
fn file_descriptor() -> Option<prost_types::FileDescriptorProto> {
None
}
fn file_descriptors() -> Vec<prost_types::FileDescriptorProto> {
Self::file_descriptor().into_iter().collect()
}
fn repeating() -> bool {
false
}
fn optional() -> bool {
false
}
fn encoded_len(&self) -> usize;
fn encoded_len_tagged(&self, field_number: u32) -> usize {
let tag = ((field_number << 3) | Self::wire_type()) as u64;
encoded_len_varint(tag) + self.encoded_len()
}
}
impl ProtobufField for u64 {
fn field_type() -> ProstFieldType {
ProstFieldType::Uint64
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
encode_varint(*self, buf);
}
fn encoded_len(&self) -> usize {
prost::encoding::encoded_len_varint(*self)
}
}
impl ProtobufField for usize {
fn field_type() -> ProstFieldType {
ProstFieldType::Uint64
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
encode_varint(*self as u64, buf);
}
fn encoded_len(&self) -> usize {
prost::encoding::encoded_len_varint(*self as u64)
}
}
const _: () = assert!(
usize::BITS <= u64::BITS,
"Target architecture has a usize larger than u64"
);
impl ProtobufField for u32 {
fn field_type() -> ProstFieldType {
ProstFieldType::Uint32
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
encode_varint((*self).into(), buf);
}
fn encoded_len(&self) -> usize {
prost::encoding::encoded_len_varint(*self as u64)
}
}
impl ProtobufField for u16 {
fn field_type() -> ProstFieldType {
ProstFieldType::Uint32
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
encode_varint((*self).into(), buf);
}
fn encoded_len(&self) -> usize {
prost::encoding::encoded_len_varint(*self as u64)
}
}
impl ProtobufField for u8 {
fn field_type() -> ProstFieldType {
ProstFieldType::Uint32
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
encode_varint((*self).into(), buf);
}
fn encoded_len(&self) -> usize {
prost::encoding::encoded_len_varint(*self as u64)
}
}
impl ProtobufField for i64 {
fn field_type() -> ProstFieldType {
ProstFieldType::Sint64
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
let n = *self as i128;
let encoded = ((n << 1) ^ (n >> 63)) as u64;
encode_varint(encoded, buf);
}
fn encoded_len(&self) -> usize {
let n = *self as i128;
let encoded = ((n << 1) ^ (n >> 63)) as u64;
prost::encoding::encoded_len_varint(encoded)
}
}
impl ProtobufField for i32 {
fn field_type() -> ProstFieldType {
ProstFieldType::Sint32
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
let n = *self as i64;
let encoded = ((n << 1) ^ (n >> 31)) as u64;
encode_varint(encoded, buf);
}
fn encoded_len(&self) -> usize {
let n = *self as i64;
let encoded = ((n << 1) ^ (n >> 31)) as u64;
prost::encoding::encoded_len_varint(encoded)
}
}
impl ProtobufField for i16 {
fn field_type() -> ProstFieldType {
<i32 as ProtobufField>::field_type()
}
fn wire_type() -> u32 {
<i32 as ProtobufField>::wire_type()
}
fn write(&self, buf: &mut impl bytes::BufMut) {
let n = *self as i32;
let encoded = ((n << 1) ^ (n >> 15)) as u64;
encode_varint(encoded, buf);
}
fn encoded_len(&self) -> usize {
let n = *self as i32;
let encoded = ((n << 1) ^ (n >> 15)) as u64;
prost::encoding::encoded_len_varint(encoded)
}
}
impl ProtobufField for i8 {
fn field_type() -> ProstFieldType {
<i32 as ProtobufField>::field_type()
}
fn wire_type() -> u32 {
<i32 as ProtobufField>::wire_type()
}
fn write(&self, buf: &mut impl bytes::BufMut) {
let n = *self as i16;
let encoded = ((n << 1) ^ (n >> 7)) as u64;
encode_varint(encoded, buf);
}
fn encoded_len(&self) -> usize {
let n = *self as i16;
let encoded = ((n << 1) ^ (n >> 7)) as u64;
prost::encoding::encoded_len_varint(encoded)
}
}
impl ProtobufField for bool {
fn field_type() -> ProstFieldType {
ProstFieldType::Bool
}
fn wire_type() -> u32 {
prost::encoding::WireType::Varint as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
buf.put_u8(*self as u8);
}
fn encoded_len(&self) -> usize {
1
}
}
impl ProtobufField for f32 {
fn field_type() -> ProstFieldType {
ProstFieldType::Float
}
fn wire_type() -> u32 {
prost::encoding::WireType::ThirtyTwoBit as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
buf.put_f32_le(*self);
}
fn encoded_len(&self) -> usize {
4 }
}
impl ProtobufField for f64 {
fn field_type() -> ProstFieldType {
ProstFieldType::Double
}
fn wire_type() -> u32 {
prost::encoding::WireType::SixtyFourBit as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
buf.put_f64_le(*self);
}
fn encoded_len(&self) -> usize {
8 }
}
impl ProtobufField for String {
fn field_type() -> ProstFieldType {
ProstFieldType::String
}
fn wire_type() -> u32 {
prost::encoding::WireType::LengthDelimited as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
prost::encoding::encode_length_delimiter(self.len(), buf).expect("Failed to write string");
buf.put_slice(self.as_bytes());
}
fn encoded_len(&self) -> usize {
let delim_len = prost::encoding::length_delimiter_len(self.len());
delim_len + self.len()
}
}
impl ProtobufField for &str {
fn field_type() -> ProstFieldType {
<String as ProtobufField>::field_type()
}
fn wire_type() -> u32 {
<String as ProtobufField>::wire_type()
}
fn write(&self, buf: &mut impl bytes::BufMut) {
prost::encoding::encode_length_delimiter(self.len(), buf).expect("Failed to write str");
buf.put_slice(self.as_bytes());
}
fn encoded_len(&self) -> usize {
let delim_len = prost::encoding::length_delimiter_len(self.len());
delim_len + self.len()
}
}
impl ProtobufField for bytes::Bytes {
fn field_type() -> ProstFieldType {
ProstFieldType::Bytes
}
fn wire_type() -> u32 {
prost::encoding::WireType::LengthDelimited as u32
}
fn write(&self, buf: &mut impl bytes::BufMut) {
prost::encoding::encode_length_delimiter(self.len(), buf).expect("Failed to write bytes");
buf.put_slice(self);
}
fn encoded_len(&self) -> usize {
let delim_len = prost::encoding::length_delimiter_len(self.len());
delim_len + self.len()
}
}
impl<T> ProtobufField for Vec<T>
where
T: ProtobufField,
{
fn field_type() -> ProstFieldType {
T::field_type()
}
fn wire_type() -> u32 {
prost::encoding::WireType::LengthDelimited as u32
}
fn write_tagged(&self, field_number: u32, buf: &mut impl bytes::BufMut) {
for value in self {
value.write_tagged(field_number, buf);
}
}
fn write(&self, _buf: &mut impl bytes::BufMut) {
panic!("Vec<T> should always be written using write_tagged");
}
fn repeating() -> bool {
true
}
fn enum_descriptor() -> Option<prost_types::EnumDescriptorProto> {
T::enum_descriptor()
}
fn message_descriptor() -> Option<prost_types::DescriptorProto> {
T::message_descriptor()
}
fn file_descriptor() -> Option<prost_types::FileDescriptorProto> {
T::file_descriptor()
}
fn file_descriptors() -> Vec<prost_types::FileDescriptorProto> {
T::file_descriptors()
}
fn type_name() -> Option<String> {
T::type_name()
}
fn encoded_len(&self) -> usize {
self.iter().map(|value| value.encoded_len()).sum()
}
fn encoded_len_tagged(&self, field_number: u32) -> usize {
self.iter()
.map(|value| value.encoded_len_tagged(field_number))
.sum()
}
}
impl<T, const N: usize> ProtobufField for [T; N]
where
T: ProtobufField,
{
fn field_type() -> ProstFieldType {
T::field_type()
}
fn wire_type() -> u32 {
prost::encoding::WireType::LengthDelimited as u32
}
fn write_tagged(&self, field_number: u32, buf: &mut impl bytes::BufMut) {
for value in self {
value.write_tagged(field_number, buf);
}
}
fn write(&self, _buf: &mut impl bytes::BufMut) {
panic!("[T; N] should always be written using write_tagged");
}
fn repeating() -> bool {
true
}
fn enum_descriptor() -> Option<prost_types::EnumDescriptorProto> {
T::enum_descriptor()
}
fn message_descriptor() -> Option<prost_types::DescriptorProto> {
T::message_descriptor()
}
fn file_descriptor() -> Option<prost_types::FileDescriptorProto> {
T::file_descriptor()
}
fn file_descriptors() -> Vec<prost_types::FileDescriptorProto> {
T::file_descriptors()
}
fn type_name() -> Option<String> {
T::type_name()
}
fn encoded_len(&self) -> usize {
self.iter().map(|value| value.encoded_len()).sum()
}
fn encoded_len_tagged(&self, field_number: u32) -> usize {
self.iter()
.map(|value| value.encoded_len_tagged(field_number))
.sum()
}
}
impl<T> ProtobufField for Option<T>
where
T: ProtobufField,
{
fn field_type() -> ProstFieldType {
T::field_type()
}
fn wire_type() -> u32 {
T::wire_type()
}
fn write_tagged(&self, field_number: u32, buf: &mut impl bytes::BufMut) {
if let Some(value) = self {
value.write_tagged(field_number, buf);
}
}
fn write(&self, _buf: &mut impl bytes::BufMut) {
panic!("Option<T> should always be written using write_tagged");
}
fn message_descriptor() -> Option<prost_types::DescriptorProto> {
T::message_descriptor()
}
fn enum_descriptor() -> Option<prost_types::EnumDescriptorProto> {
T::enum_descriptor()
}
fn file_descriptor() -> Option<prost_types::FileDescriptorProto> {
T::file_descriptor()
}
fn file_descriptors() -> Vec<prost_types::FileDescriptorProto> {
T::file_descriptors()
}
fn type_name() -> Option<String> {
T::type_name()
}
fn repeating() -> bool {
T::repeating()
}
fn optional() -> bool {
true
}
fn encoded_len(&self) -> usize {
match self {
Some(value) => value.encoded_len(),
None => 0,
}
}
fn encoded_len_tagged(&self, field_number: u32) -> usize {
match self {
Some(value) => value.encoded_len_tagged(field_number),
None => 0,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_u8_encoded_len() {
assert_eq!(ProstFieldType::Uint32, u8::field_type());
assert_eq!(1, u8::encoded_len(&127u8));
assert_eq!(2, u8::encoded_len(&128u8));
}
#[test]
fn test_i8_encoded_len() {
assert_eq!(ProstFieldType::Sint32, i8::field_type());
assert_eq!(1, (-1i8).encoded_len());
assert_eq!(1, 1i8.encoded_len());
assert_eq!(2, i8::MIN.encoded_len());
assert_eq!(2, i8::MAX.encoded_len());
}
#[test]
fn test_i8_write() {
let cases: Vec<(i8, &[u8])> = vec![
(-1i8, &[1]),
(1i8, &[2]),
(-127i8, &[253, 1]),
(127i8, &[254, 1]),
];
for (input, expected) in cases {
let mut buf = bytes::BytesMut::new();
i8::write(&input, &mut buf);
assert_eq!(&buf[..], expected);
let mut buf = bytes::BytesMut::new();
i16::write(&(input as i16), &mut buf);
assert_eq!(&buf[..], expected);
let mut buf = bytes::BytesMut::new();
i32::write(&(input as i32), &mut buf);
assert_eq!(&buf[..], expected);
let mut buf = bytes::BytesMut::new();
i64::write(&(input as i64), &mut buf);
assert_eq!(&buf[..], expected);
}
}
#[test]
fn test_i64_edges() {
let mut buf = bytes::BytesMut::new();
i64::write(&(i64::MAX), &mut buf);
assert_eq!(
&buf[..],
&[0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
);
assert_eq!(i64::MAX.encoded_len(), 10);
let mut buf = bytes::BytesMut::new();
i64::write(&(i64::MIN), &mut buf);
assert_eq!(
&buf[..],
&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
);
assert_eq!(i64::MIN.encoded_len(), 10);
}
#[test]
fn test_write_tagged() {
let mut buf = bytes::BytesMut::new();
bool::write_tagged(&true, 1, &mut buf);
assert_eq!(&buf[..], &[0x08, 0x01]);
let mut buf = bytes::BytesMut::new();
bool::write_tagged(&true, 256, &mut buf);
assert_eq!(&buf[..], &[0x80, 0x10, 0x01]);
}
#[test]
fn test_usize_field_type() {
assert_eq!(ProstFieldType::Uint64, usize::field_type());
}
#[test]
fn test_usize_encoded_len() {
assert_eq!(1, usize::encoded_len(&0));
assert_eq!(1, usize::encoded_len(&127));
assert_eq!(2, usize::encoded_len(&128));
#[cfg(target_pointer_width = "64")]
{
assert_eq!(10, usize::encoded_len(&usize::MAX));
}
#[cfg(target_pointer_width = "32")]
{
assert_eq!(5, usize::encoded_len(&usize::MAX));
}
}
#[test]
fn test_usize_write() {
let mut buf = bytes::BytesMut::new();
usize::write(&42, &mut buf);
assert_eq!(&buf[..], &[42]);
#[cfg(target_pointer_width = "64")]
{
let mut buf = bytes::BytesMut::new();
usize::write(&usize::MAX, &mut buf);
assert_eq!(
&buf[..],
&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
);
}
#[cfg(target_pointer_width = "32")]
{
let mut buf = bytes::BytesMut::new();
usize::write(&usize::MAX, &mut buf);
assert_eq!(&buf[..], &[0xff, 0xff, 0xff, 0xff, 0x0f]);
}
}
#[test]
fn test_usize_matches_u64() {
let test_values = vec![
0usize,
1,
127,
128,
255,
256,
65535,
65536,
u32::MAX as usize,
];
for val in test_values {
let mut buf_usize = bytes::BytesMut::new();
usize::write(&val, &mut buf_usize);
let mut buf_u64 = bytes::BytesMut::new();
u64::write(&(val as u64), &mut buf_u64);
assert_eq!(
&buf_usize[..],
&buf_u64[..],
"usize and u64 should encode identically for value {}",
val
);
assert_eq!(usize::encoded_len(&val), u64::encoded_len(&(val as u64)));
}
}
}