1mod borrowed;
2pub use borrowed::{BytesRef, TextRef};
3
4use crate::{Error, Shape, Wire};
5use alloc::{string::String, vec::Vec};
6use core::fmt;
7use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
8
9#[derive(Clone, Debug, Eq, PartialEq)]
11pub struct List<T, const N: usize>(Vec<T>);
12impl<T, const N: usize> List<T, N> {
13 pub fn new(values: Vec<T>) -> Result<Self, Error> {
15 if values.len() > N {
16 Err(Error::Limit)
17 } else {
18 Ok(Self(values))
19 }
20 }
21 pub fn as_slice(&self) -> &[T] {
23 &self.0
24 }
25 pub fn into_vec(self) -> Vec<T> {
27 self.0
28 }
29}
30impl<T: Serialize, const N: usize> Serialize for List<T, N> {
31 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
32 self.0.serialize(s)
33 }
34}
35impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for List<T, N> {
36 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
37 struct Visitor<T, const N: usize>(core::marker::PhantomData<T>);
38 impl<'de, T: Deserialize<'de>, const N: usize> de::Visitor<'de> for Visitor<T, N> {
39 type Value = List<T, N>;
40 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.write_str("bounded sequence")
42 }
43 fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
44 let count = seq.size_hint();
47 if count.is_some_and(|count| count > N) {
48 return Err(de::Error::custom("element limit"));
49 }
50 let mut values = Vec::new();
51 values
52 .try_reserve_exact(count.unwrap_or(0))
53 .map_err(|_| de::Error::custom("allocation"))?;
54 for _ in 0..N {
55 let Some(value) = seq.next_element()? else {
56 return Ok(List(values));
57 };
58 if values.len() == values.capacity() {
59 let next = values.len().saturating_mul(2).max(1).min(N);
62 values
63 .try_reserve_exact(next - values.len())
64 .map_err(|_| de::Error::custom("allocation"))?;
65 }
66 values.push(value);
67 }
68 struct Reject;
70 impl<'de> de::DeserializeSeed<'de> for Reject {
71 type Value = ();
72 fn deserialize<D: Deserializer<'de>>(self, _: D) -> Result<(), D::Error> {
73 Err(de::Error::custom("element limit"))
74 }
75 }
76 seq.next_element_seed(Reject)?;
77 Ok(List(values))
78 }
79 }
80 d.deserialize_seq(Visitor::<T, N>(core::marker::PhantomData))
81 }
82}
83impl<T: Wire, const N: usize> Wire for List<T, N> {
84 const SCHEMA: crate::schema::Schema = crate::schema::Schema::List(&T::SCHEMA, N);
85 const SHAPE: Shape = Shape {
86 bytes: 10_usize.saturating_add(T::SHAPE.bytes.saturating_mul(N)),
87 heap: N.saturating_mul(core::mem::size_of::<T>().saturating_add(T::SHAPE.heap)),
88 nodes: 1_usize.saturating_add(N.saturating_mul(T::SHAPE.nodes)),
89 depth: T::SHAPE.depth.saturating_add(1),
90 };
91}
92
93#[derive(Clone, Debug, Eq, PartialEq)]
96pub struct Bytes<const N: usize>(Vec<u8>);
97impl<const N: usize> Bytes<N> {
98 pub fn new(bytes: Vec<u8>) -> Result<Self, Error> {
100 if bytes.len() > N {
101 Err(Error::Limit)
102 } else {
103 Ok(Self(bytes))
104 }
105 }
106 pub fn as_slice(&self) -> &[u8] {
108 &self.0
109 }
110 pub fn as_borrowed(&self) -> BytesRef<'_, N> {
112 BytesRef::from_owned(self)
113 }
114 pub fn into_vec(self) -> Vec<u8> {
116 self.0
117 }
118}
119impl<const N: usize> Serialize for Bytes<N> {
120 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
121 s.serialize_bytes(&self.0)
122 }
123}
124impl<'de, const N: usize> Deserialize<'de> for Bytes<N> {
125 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
126 struct Visitor<const N: usize>;
127 impl<const N: usize> de::Visitor<'_> for Visitor<N> {
128 type Value = Bytes<N>;
129 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 f.write_str("bounded bytes")
131 }
132 fn visit_bytes<E: de::Error>(self, bytes: &[u8]) -> Result<Self::Value, E> {
133 if bytes.len() > N {
134 return Err(E::custom("byte limit"));
135 }
136 let mut out = Vec::new();
137 out.try_reserve_exact(bytes.len())
138 .map_err(|_| E::custom("allocation"))?;
139 out.extend_from_slice(bytes);
140 Ok(Bytes(out))
141 }
142 }
143 d.deserialize_bytes(Visitor::<N>)
144 }
145}
146impl<const N: usize> Wire for Bytes<N> {
147 const SCHEMA: crate::schema::Schema = crate::schema::Schema::Bytes(N);
148 const SHAPE: Shape = Shape {
149 bytes: N.saturating_add(10),
150 heap: N,
151 nodes: 1,
152 depth: 1,
153 };
154}
155
156#[derive(Clone, Debug, Eq, PartialEq)]
158pub struct Text<const N: usize>(String);
159impl<const N: usize> Text<N> {
160 pub fn new(text: String) -> Result<Self, Error> {
162 if text.len() > N {
163 Err(Error::Limit)
164 } else {
165 Ok(Self(text))
166 }
167 }
168 pub fn as_str(&self) -> &str {
170 &self.0
171 }
172 pub fn as_borrowed(&self) -> TextRef<'_, N> {
174 TextRef::from_owned(self)
175 }
176 pub fn into_string(self) -> String {
178 self.0
179 }
180}
181impl<const N: usize> Serialize for Text<N> {
182 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
183 s.serialize_str(&self.0)
184 }
185}
186impl<'de, const N: usize> Deserialize<'de> for Text<N> {
187 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
188 let bytes = Bytes::<N>::deserialize(d)?;
189 let text = String::from_utf8(bytes.0).map_err(|_| de::Error::custom("invalid UTF-8"))?;
190 Ok(Self(text))
191 }
192}
193impl<const N: usize> Wire for Text<N> {
194 const SCHEMA: crate::schema::Schema = crate::schema::Schema::Text(N);
195 const SHAPE: Shape = Bytes::<N>::SHAPE;
196}