length_delimited/
string.rs1use dbutils::{
2 error::{IncompleteBuffer, InsufficientBuffer},
3 leb128::*,
4};
5
6macro_rules! string_impl {
7 ($($ty:ty:$converter:ident),+$(,)?) => {
8 string_impl!(@encoder $($ty),+);
9 string_impl!(@decoder $($ty:$converter),+);
10 };
11 (@encoder $($ty:ty),+$(,)?) => {
12 $(
13 impl crate::LengthDelimitedEncoder for $ty {
14 type Error = InsufficientBuffer;
15
16 fn encoded_len(&self) -> usize {
17 <&[u8] as crate::LengthDelimitedEncoder>::encoded_len(&self.as_bytes())
18 }
19
20 fn encoded_length_delimited_len(&self) -> usize {
21 <&[u8] as crate::LengthDelimitedEncoder>::encoded_length_delimited_len(&self.as_bytes())
22 }
23
24 fn encode_length_delimited(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
25 <&[u8] as crate::LengthDelimitedEncoder>::encode_length_delimited(&self.as_bytes(), buf)
26 }
27
28 fn encode(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
29 <&[u8] as crate::LengthDelimitedEncoder>::encode(&self.as_bytes(), buf)
30 }
31 }
32 )*
33 };
34 (@decoder $($ty:ty:$converter:ident),+$(,)?) => {
35 $(
36 impl crate::LengthDelimitedDecoder for $ty {
37 type Error = DecodeUtf8BytesError;
38
39 fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error>
40 where
41 Self: Sized,
42 {
43 core::str::from_utf8(&src).map_err(Into::into).map(|s| (src.len(), Self::$converter(s)))
44 }
45
46 fn decode_length_delimited(src: &[u8]) -> Result<(usize, Self), Self::Error>
47 where
48 Self: Sized,
49 {
50 let (read, bytes) = decode_u64_varint(src)?;
51 let len = bytes as usize;
52 let required = read + len;
53 if required > src.len() {
54 return Err(IncompleteBuffer::with_information(required as u64, src.len() as u64).into());
55 }
56
57 Self::decode(&src[read..required])
58 .map(|(bytes, this)| (read + bytes, this))
59 .map_err(|e| match e {
60 Self::Error::IncompleteBuffer(_) => IncompleteBuffer::with_information(
61 required as u64,
62 src.len() as u64,
63 ).into(),
64 e => e,
65 })
66 }
67 }
68 )*
69 };
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
74pub enum DecodeUtf8BytesError {
75 #[error(transparent)]
77 IncompleteBuffer(#[from] IncompleteBuffer),
78 #[error("length delimited overflow")]
80 Overflow,
81 #[error(transparent)]
83 Utf8(#[from] core::str::Utf8Error),
84}
85
86impl From<DecodeVarintError> for DecodeUtf8BytesError {
87 fn from(e: DecodeVarintError) -> Self {
88 match e {
89 DecodeVarintError::Underflow => Self::IncompleteBuffer(IncompleteBuffer::new()),
90 DecodeVarintError::Overflow => Self::Overflow,
91 }
92 }
93}
94
95impl From<crate::DecodeBytesError> for DecodeUtf8BytesError {
96 fn from(e: crate::DecodeBytesError) -> Self {
97 match e {
98 crate::DecodeBytesError::IncompleteBuffer(e) => Self::IncompleteBuffer(e),
99 crate::DecodeBytesError::Overflow => Self::Overflow,
100 }
101 }
102}
103
104string_impl!(@encoder &str);
105
106#[cfg(any(feature = "std", feature = "alloc"))]
107string_impl!(std::string::String:from, std::sync::Arc<str>:from, std::boxed::Box<str>:from, std::rc::Rc<str>:from);
108
109#[cfg(all(feature = "triomphe01", any(feature = "std", feature = "alloc")))]
110string_impl!(triomphe01::Arc<str>:from,);
111
112#[cfg(all(feature = "smol_str03", any(feature = "std", feature = "alloc")))]
113string_impl!(smol_str03::SmolStr:new,);
114
115#[cfg(all(feature = "faststr02", any(feature = "std", feature = "alloc")))]
116string_impl!(faststr02::FastStr:new,);