bincode_next/features/
bounded.rs1#![cfg(feature = "alloc")]
7
8use crate::de::BorrowDecode;
9use crate::de::BorrowDecoder;
10use crate::de::Decode;
11use crate::de::Decoder;
12use crate::de::read::Reader;
13use crate::enc::Encode;
14use crate::enc::Encoder;
15use crate::error::DecodeError;
16use crate::error::EncodeError;
17use crate::static_size::StaticSize;
18use crate::static_size::helpers::VARINT_MAX_64;
19use alloc::string::String;
20use alloc::vec::Vec;
21
22#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
27pub struct BoundedVec<T, const CAP: usize>(pub Vec<T>);
28
29impl<T, const CAP: usize> StaticSize for BoundedVec<T, CAP>
30where
31 T: StaticSize,
32{
33 const MAX_SIZE: usize = VARINT_MAX_64 + T::MAX_SIZE * CAP;
34}
35
36impl<T: Encode, const CAP: usize> Encode for BoundedVec<T, CAP> {
37 #[inline]
38 fn encode<E: Encoder>(
39 &self,
40 encoder: &mut E,
41 ) -> Result<(), EncodeError> {
42 if self.0.len() > CAP {
43 return crate::error::cold_encode_error_other("BoundedVec exceeds capacity");
44 }
45 self.0.encode(encoder)
46 }
47}
48
49impl<Context, T: Decode<Context>, const CAP: usize> Decode<Context> for BoundedVec<T, CAP> {
50 #[inline]
51 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
52 let len = crate::de::decode_slice_len(decoder)?;
54 if len > CAP {
55 return crate::error::cold_decode_error_other("BoundedVec length exceeds capacity");
56 }
57
58 decoder.claim_container_read::<T>(len)?;
59 let mut vec = Vec::with_capacity(len);
60 for _ in 0..len {
61 decoder.unclaim_bytes_read(core::mem::size_of::<T>());
62 vec.push(T::decode(decoder)?);
63 }
64 Ok(Self(vec))
65 }
66}
67
68impl<'de, Context, T: BorrowDecode<'de, Context>, const CAP: usize> BorrowDecode<'de, Context>
69 for BoundedVec<T, CAP>
70{
71 fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
72 decoder: &mut D
73 ) -> Result<Self, DecodeError> {
74 let len = crate::de::decode_slice_len(decoder)?;
76 if len > CAP {
77 return crate::error::cold_decode_error_other("BoundedVec length exceeds capacity");
78 }
79
80 decoder.claim_container_read::<T>(len)?;
81 let mut vec = Vec::with_capacity(len);
82 for _ in 0..len {
83 decoder.unclaim_bytes_read(core::mem::size_of::<T>());
84 vec.push(T::borrow_decode(decoder)?);
85 }
86 Ok(Self(vec))
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
95pub struct BoundedString<const CAP: usize>(pub String);
96
97impl<const CAP: usize> StaticSize for BoundedString<CAP> {
98 const MAX_SIZE: usize = VARINT_MAX_64 + CAP;
99}
100
101impl<const CAP: usize> Encode for BoundedString<CAP> {
102 #[inline]
103 fn encode<E: Encoder>(
104 &self,
105 encoder: &mut E,
106 ) -> Result<(), EncodeError> {
107 if self.0.len() > CAP {
108 return crate::error::cold_encode_error_other("BoundedString exceeds capacity");
109 }
110 self.0.encode(encoder)
111 }
112}
113
114impl<Context, const CAP: usize> Decode<Context> for BoundedString<CAP> {
115 #[inline]
116 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
117 let len = crate::de::decode_slice_len(decoder)?;
119 if len > CAP {
120 return crate::error::cold_decode_error_other("BoundedString length exceeds capacity");
121 }
122
123 decoder.claim_container_read::<u8>(len)?;
124 let mut bytes = alloc::vec![0u8; len];
125 decoder.reader().read(&mut bytes)?;
126 let s = String::from_utf8(bytes)
127 .map_err(|e| crate::error::cold_decode_error_utf8::<()>(e.utf8_error()).unwrap_err())?;
128 Ok(Self(s))
129 }
130}
131
132impl<'de, Context, const CAP: usize> BorrowDecode<'de, Context> for BoundedString<CAP> {
133 fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
134 decoder: &mut D
135 ) -> Result<Self, DecodeError> {
136 let len = crate::de::decode_slice_len(decoder)?;
138 if len > CAP {
139 return crate::error::cold_decode_error_other("BoundedString length exceeds capacity");
140 }
141
142 decoder.claim_container_read::<u8>(len)?;
143 let mut bytes = alloc::vec![0u8; len];
144 decoder.reader().read(&mut bytes)?;
145 let s = String::from_utf8(bytes)
146 .map_err(|e| crate::error::cold_decode_error_utf8::<()>(e.utf8_error()).unwrap_err())?;
147 Ok(Self(s))
148 }
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
153pub struct BoundsExceeded;
154
155impl core::fmt::Display for BoundsExceeded {
156 #[inline]
157 fn fmt(
158 &self,
159 f: &mut core::fmt::Formatter<'_>,
160 ) -> core::fmt::Result {
161 write!(f, "value exceeds bounded capacity")
162 }
163}
164
165impl<T, const CAP: usize> TryFrom<Vec<T>> for BoundedVec<T, CAP> {
166 type Error = BoundsExceeded;
167
168 #[inline]
169 fn try_from(v: Vec<T>) -> Result<Self, Self::Error> {
170 if v.len() > CAP {
171 Err(BoundsExceeded)
172 } else {
173 Ok(Self(v))
174 }
175 }
176}
177
178impl<const CAP: usize> TryFrom<String> for BoundedString<CAP> {
179 type Error = BoundsExceeded;
180
181 #[inline]
182 fn try_from(s: String) -> Result<Self, Self::Error> {
183 if s.len() > CAP {
184 Err(BoundsExceeded)
185 } else {
186 Ok(Self(s))
187 }
188 }
189}
190
191impl<T, const CAP: usize> BoundedVec<T, CAP> {
192 #[must_use]
194 #[inline(always)]
195 pub const fn new() -> Self {
196 Self(Vec::new())
197 }
198
199 #[inline]
205 pub fn try_push(
206 &mut self,
207 value: T,
208 ) -> Result<(), BoundsExceeded> {
209 if self.0.len() >= CAP {
210 Err(BoundsExceeded)
211 } else {
212 self.0.push(value);
213 Ok(())
214 }
215 }
216
217 #[must_use]
219 #[inline(always)]
220 pub fn into_inner(self) -> Vec<T> {
221 self.0
222 }
223}
224
225impl<T, const CAP: usize> Default for BoundedVec<T, CAP> {
226 #[inline(always)]
227 fn default() -> Self {
228 Self::new()
229 }
230}
231
232impl<const CAP: usize> BoundedString<CAP> {
233 #[must_use]
235 #[inline(always)]
236 pub const fn new() -> Self {
237 Self(String::new())
238 }
239
240 #[must_use]
242 #[inline(always)]
243 pub fn into_inner(self) -> String {
244 self.0
245 }
246}
247
248impl<const CAP: usize> Default for BoundedString<CAP> {
249 #[inline(always)]
250 fn default() -> Self {
251 Self::new()
252 }
253}
254
255impl<T, const CAP: usize> core::ops::Deref for BoundedVec<T, CAP> {
256 type Target = Vec<T>;
257
258 #[inline(always)]
259 fn deref(&self) -> &Self::Target {
260 &self.0
261 }
262}
263
264impl<const CAP: usize> core::ops::Deref for BoundedString<CAP> {
265 type Target = String;
266
267 #[inline(always)]
268 fn deref(&self) -> &Self::Target {
269 &self.0
270 }
271}