1mod borrowed;
2mod packed_i16;
3pub use borrowed::{BytesRef, TextRef};
4pub use packed_i16::PackedI16;
5
6use crate::Error;
7use alloc::{string::String, vec::Vec};
8use core::fmt;
9use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
10
11#[derive(Clone, Debug, Eq, PartialEq)]
13pub struct List<T, const N: usize>(Vec<T>);
14impl<T, const N: usize> List<T, N> {
15 pub fn new(values: Vec<T>) -> Result<Self, Error> {
17 if values.len() > N {
18 Err(Error::Limit)
19 } else {
20 Ok(Self(values))
21 }
22 }
23 pub fn as_slice(&self) -> &[T] {
25 &self.0
26 }
27 pub fn into_vec(self) -> Vec<T> {
29 self.0
30 }
31}
32impl<T: Serialize, const N: usize> Serialize for List<T, N> {
33 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
34 self.0.serialize(s)
35 }
36}
37impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for List<T, N> {
38 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
39 d.deserialize_seq(ListVisitor::<T, N>(core::marker::PhantomData))
40 .map(Self)
41 }
42}
43
44struct ListVisitor<T, const N: usize>(core::marker::PhantomData<T>);
45impl<'de, T: Deserialize<'de>, const N: usize> de::Visitor<'de> for ListVisitor<T, N> {
46 type Value = Vec<T>;
47 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.write_str("bounded sequence")
49 }
50 fn visit_seq<A: de::SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
51 if size_of::<T>() == 0 || N <= 1 {
56 read_list(seq, N)
57 } else {
58 read_list_shared(seq, N)
59 }
60 }
61}
62
63#[inline(never)]
64fn read_list_shared<'de, T: Deserialize<'de>, A: de::SeqAccess<'de>>(
65 seq: A,
66 limit: usize,
67) -> Result<Vec<T>, A::Error> {
68 read_list(seq, limit)
69}
70
71#[inline(always)]
72fn read_list<'de, T: Deserialize<'de>, A: de::SeqAccess<'de>>(
73 mut seq: A,
74 limit: usize,
75) -> Result<Vec<T>, A::Error> {
76 let count = seq.size_hint();
79 if count.is_some_and(|count| count > limit) {
80 return Err(de::Error::custom("element limit"));
81 }
82 let mut values = Vec::new();
83 values
84 .try_reserve_exact(count.unwrap_or(0))
85 .map_err(|_| de::Error::custom("allocation"))?;
86 for _ in 0..limit {
87 let Some(value) = seq.next_element()? else {
88 return Ok(values);
89 };
90 if values.len() == values.capacity() {
91 let next = values.len().saturating_mul(2).max(1).min(limit);
94 values
95 .try_reserve_exact(next - values.len())
96 .map_err(|_| de::Error::custom("allocation"))?;
97 }
98 values.push(value);
99 }
100 struct Reject;
102 impl<'de> de::DeserializeSeed<'de> for Reject {
103 type Value = ();
104 fn deserialize<D: Deserializer<'de>>(self, _: D) -> Result<(), D::Error> {
105 Err(de::Error::custom("element limit"))
106 }
107 }
108 seq.next_element_seed(Reject)?;
109 Ok(values)
110}
111
112#[derive(Clone, Debug, Eq, PartialEq)]
115pub struct Bytes<const N: usize>(Vec<u8>);
116impl<const N: usize> Bytes<N> {
117 pub fn new(bytes: Vec<u8>) -> Result<Self, Error> {
119 if bytes.len() > N {
120 Err(Error::Limit)
121 } else {
122 Ok(Self(bytes))
123 }
124 }
125 pub fn as_slice(&self) -> &[u8] {
127 &self.0
128 }
129 pub fn as_borrowed(&self) -> BytesRef<'_, N> {
131 BytesRef::from_owned(self)
132 }
133 pub fn into_vec(self) -> Vec<u8> {
135 self.0
136 }
137}
138impl<const N: usize> Serialize for Bytes<N> {
139 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
140 s.serialize_bytes(&self.0)
141 }
142}
143impl<'de, const N: usize> Deserialize<'de> for Bytes<N> {
144 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
145 d.deserialize_bytes(BytesVisitor { limit: N }).map(Self)
146 }
147}
148
149struct BytesVisitor {
153 limit: usize,
154}
155impl de::Visitor<'_> for BytesVisitor {
156 type Value = Vec<u8>;
157 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 f.write_str("bounded bytes")
159 }
160 #[inline(never)]
161 fn visit_bytes<E: de::Error>(self, bytes: &[u8]) -> Result<Self::Value, E> {
162 if bytes.len() > self.limit {
163 return Err(E::custom("byte limit"));
164 }
165 let mut out = Vec::new();
166 out.try_reserve_exact(bytes.len())
167 .map_err(|_| E::custom("allocation"))?;
168 out.extend_from_slice(bytes);
169 Ok(out)
170 }
171}
172
173#[derive(Clone, Debug, Eq, PartialEq)]
175pub struct Text<const N: usize>(String);
176impl<const N: usize> Text<N> {
177 pub fn new(text: String) -> Result<Self, Error> {
179 if text.len() > N {
180 Err(Error::Limit)
181 } else {
182 Ok(Self(text))
183 }
184 }
185 pub fn as_str(&self) -> &str {
187 &self.0
188 }
189 pub fn as_borrowed(&self) -> TextRef<'_, N> {
191 TextRef::from_owned(self)
192 }
193 pub fn into_string(self) -> String {
195 self.0
196 }
197}
198impl<const N: usize> Serialize for Text<N> {
199 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
200 s.serialize_str(&self.0)
201 }
202}
203impl<'de, const N: usize> Deserialize<'de> for Text<N> {
204 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
205 let bytes = Bytes::<N>::deserialize(d)?;
206 let text = String::from_utf8(bytes.0).map_err(|_| de::Error::custom("invalid UTF-8"))?;
207 Ok(Self(text))
208 }
209}