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