#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(rustdoc::broken_intra_doc_links)]
#[doc(hidden)]
pub extern crate alloc;
#[doc(hidden)]
pub use ::bytes;
#[cfg(feature = "json")]
#[doc(hidden)]
pub use ::serde_json;
#[macro_export]
macro_rules! include_proto {
($pkg:literal) => {
include!(concat!(env!("OUT_DIR"), "/", $pkg, ".mod.rs"));
};
}
#[macro_export]
macro_rules! include_proto_relative {
($dir:literal, $pkg:literal) => {
include!(concat!($dir, "/", $pkg, ".mod.rs"));
};
}
#[cfg(test)]
pub(crate) fn test_ctx(depth: u32) -> DecodeContext<'static> {
let limit = alloc::boxed::Box::leak(alloc::boxed::Box::new(core::cell::Cell::new(
DEFAULT_UNKNOWN_FIELD_LIMIT,
)));
DecodeContext::new(depth, limit)
}
#[cfg(feature = "json")]
pub mod any_registry;
pub mod editions;
pub mod encoding;
pub mod enumeration;
pub mod error;
pub mod extension;
#[cfg(feature = "json")]
pub mod extension_registry;
#[cfg(feature = "json")]
pub mod json;
#[cfg(feature = "json")]
pub mod json_helpers;
#[doc(hidden)]
pub mod map_codec;
pub mod message;
pub mod message_field;
pub mod message_set;
pub mod oneof;
mod size_cache;
#[cfg(feature = "text")]
pub mod text;
#[cfg(any(feature = "json", feature = "text"))]
pub mod type_registry;
pub mod types;
pub mod unknown_fields;
pub mod view;
pub use enumeration::{EnumValue, Enumeration};
pub use error::{DecodeError, EncodeError};
pub use extension::{Extension, ExtensionCodec, ExtensionSet};
pub use foldhash;
pub use map_codec::{Map, MapStorage};
pub use message::{
DecodeContext, DecodeOptions, Message, MessageName, DEFAULT_UNKNOWN_FIELD_LIMIT,
RECURSION_LIMIT,
};
pub use message_field::{DefaultInstance, MessageField, ProtoBox};
pub use oneof::Oneof;
pub use size_cache::{SizeCache, SizeCachePool};
pub use types::{ProtoBytes, ProtoList, ProtoString, WirePayload};
pub use unknown_fields::{UnknownField, UnknownFieldData, UnknownFields};
#[cfg(feature = "text")]
pub use text::TextFormat;
pub use view::{
DefaultViewInstance, HasMessageView, LazyMessageFieldView, LazyMessageView, LazyRepeatedView,
MapView, MessageFieldView, MessageView, OwnedView, RepeatedView, UnknownFieldsView, ViewEncode,
ViewReborrow,
};
#[doc(hidden)]
pub mod __private {
pub use once_cell::race::OnceBox;
#[cfg(not(feature = "std"))]
pub type HashMap<K, V> = hashbrown::HashMap<K, V>;
#[cfg(feature = "std")]
pub type HashMap<K, V> = std::collections::HashMap<K, V, foldhash::fast::RandomState>;
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_string<S: crate::ProtoString>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<S> {
let s: ::alloc::string::String = ::arbitrary::Arbitrary::arbitrary(u)?;
Ok(S::from(s))
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_string_opt<S: crate::ProtoString>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<::core::option::Option<S>> {
let opt: ::core::option::Option<::alloc::string::String> =
::arbitrary::Arbitrary::arbitrary(u)?;
Ok(opt.map(S::from))
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_string_vec<S: crate::ProtoString>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<::alloc::vec::Vec<S>> {
let vv: ::alloc::vec::Vec<::alloc::string::String> = ::arbitrary::Arbitrary::arbitrary(u)?;
Ok(vv.into_iter().map(S::from).collect())
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_bytes<B: crate::ProtoBytes>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<B> {
let v: ::alloc::vec::Vec<u8> = ::arbitrary::Arbitrary::arbitrary(u)?;
Ok(B::from(v))
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_bytes_opt<B: crate::ProtoBytes>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<::core::option::Option<B>> {
let opt: ::core::option::Option<::alloc::vec::Vec<u8>> =
::arbitrary::Arbitrary::arbitrary(u)?;
Ok(opt.map(B::from))
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_bytes_vec<B: crate::ProtoBytes>(
u: &mut ::arbitrary::Unstructured<'_>,
) -> ::arbitrary::Result<::alloc::vec::Vec<B>> {
let vv: ::alloc::vec::Vec<::alloc::vec::Vec<u8>> = ::arbitrary::Arbitrary::arbitrary(u)?;
Ok(vv.into_iter().map(B::from).collect())
}
#[cfg(feature = "arbitrary")]
pub fn arbitrary_proto_bytes_map<'a, C>(
u: &mut ::arbitrary::Unstructured<'a>,
) -> ::arbitrary::Result<C>
where
C: crate::map_codec::MapStorage + Default,
C::Key: ::arbitrary::Arbitrary<'a>,
C::Value: crate::ProtoBytes,
{
let mut out = C::default();
for entry in u.arbitrary_iter::<(C::Key, ::alloc::vec::Vec<u8>)>()? {
let (k, v) = entry?;
out.storage_insert(k, <C::Value as ::core::convert::From<_>>::from(v));
}
Ok(out)
}
}
#[cfg(all(test, feature = "arbitrary"))]
mod arbitrary_tests {
use super::__private::{
arbitrary_proto_bytes, arbitrary_proto_bytes_opt, arbitrary_proto_bytes_vec,
};
use ::bytes::Bytes;
use alloc::vec::Vec;
use arbitrary::{Arbitrary, Unstructured};
const SEED: [u8; 128] = {
let mut a = [0u8; 128];
let mut i = 0;
while i < 128 {
a[i] = (i as u8).wrapping_mul(31).wrapping_add(7);
i += 1;
}
a
};
#[test]
fn arbitrary_proto_bytes_matches_vec_u8() {
let b: Bytes = arbitrary_proto_bytes(&mut Unstructured::new(&SEED)).unwrap();
let v: Vec<u8> = Arbitrary::arbitrary(&mut Unstructured::new(&SEED)).unwrap();
assert_eq!(b.as_ref(), v.as_slice());
assert!(b.len() <= SEED.len());
}
#[test]
fn arbitrary_proto_bytes_opt_matches_option_vec_u8() {
let b: Option<Bytes> = arbitrary_proto_bytes_opt(&mut Unstructured::new(&SEED)).unwrap();
let v: Option<Vec<u8>> = Arbitrary::arbitrary(&mut Unstructured::new(&SEED)).unwrap();
assert_eq!(b.is_some(), v.is_some());
assert_eq!(
b.as_ref().map(|x| x.to_vec()),
v,
"Option<Bytes> builder must mirror Option<Vec<u8>>"
);
}
#[test]
fn arbitrary_proto_bytes_vec_matches_vec_vec_u8() {
let bs: Vec<Bytes> = arbitrary_proto_bytes_vec(&mut Unstructured::new(&SEED)).unwrap();
let vs: Vec<Vec<u8>> = Arbitrary::arbitrary(&mut Unstructured::new(&SEED)).unwrap();
assert_eq!(bs.len(), vs.len());
for (b, v) in bs.iter().zip(&vs) {
assert_eq!(b.as_ref(), v.as_slice());
}
}
#[test]
fn arbitrary_proto_string_matches_string() {
use super::__private::arbitrary_proto_string;
use alloc::string::String;
let s: String = arbitrary_proto_string(&mut Unstructured::new(&SEED)).unwrap();
let v: String = Arbitrary::arbitrary(&mut Unstructured::new(&SEED)).unwrap();
assert_eq!(s, v);
}
}
#[doc(hidden)]
pub mod __doctest_fixtures {
use crate::*;
#[derive(Clone, Default, PartialEq)]
pub struct Person {
pub name: alloc::string::String,
pub id: i32,
}
impl DefaultInstance for Person {
fn default_instance() -> &'static Self {
static INST: __private::OnceBox<Person> = __private::OnceBox::new();
INST.get_or_init(|| alloc::boxed::Box::new(Self::default()))
}
}
impl Message for Person {
fn compute_size(&self, _cache: &mut SizeCache) -> u32 {
0
}
fn write_to(&self, _cache: &mut SizeCache, _buf: &mut impl bytes::BufMut) {}
fn merge_field(
&mut self,
tag: crate::encoding::Tag,
buf: &mut impl bytes::Buf,
_ctx: DecodeContext<'_>,
) -> Result<(), DecodeError> {
crate::encoding::skip_field(tag, buf)
}
fn clear(&mut self) {
*self = Self::default();
}
}
#[derive(Clone, Default)]
pub struct PersonView<'a> {
pub name: &'a str,
pub id: i32,
}
impl<'a> view::MessageView<'a> for PersonView<'a> {
type Owned = Person;
fn decode_view(_buf: &'a [u8]) -> Result<Self, DecodeError> {
Ok(PersonView::default())
}
fn merge_view_field(
&mut self,
_tag: encoding::Tag,
cur: &'a [u8],
_before_tag: &'a [u8],
_ctx: DecodeContext<'_>,
) -> Result<&'a [u8], DecodeError> {
Ok(cur)
}
fn to_owned_message(&self) -> Result<Person, DecodeError> {
Ok(Person {
name: self.name.into(),
id: self.id,
})
}
}
impl view::ViewReborrow for PersonView<'static> {
type Reborrowed<'b> = PersonView<'b>;
fn reborrow<'b>(this: &'b Self) -> &'b Self::Reborrowed<'b> {
this
}
}
}