1use crate::cxs;
2use crate::read_xdr::ReadXDR;
3use crate::serialize::reader::{ReadError, ReadResult, Reader};
4use crate::serialize::writer::{WriteResult, Writer};
5use crate::serialize::writer_unchecked::WriterUnchecked;
6use crate::txs;
7use crate::valid_u32::*;
8use crate::write_xdr::WriteXDR;
9
10use heapless::String;
11use heapless::Vec;
12
13impl<'r, const N: usize> ReadXDR<'r> for Vec<u8, N> {
14 fn read_xdr<R: Reader<'r>>(r: &mut R) -> ReadResult<Self> {
15 let () = ValidU32::<N>::OK;
16
17 let bytes = r.read_opaque_variable(N as u32)?;
18
19 let mut s = Vec::new();
20 s.extend_from_slice(bytes)
21 .map_err(|_| ReadError::max_length_exceeded())?;
22
23 Ok(s)
24 }
25}
26
27impl<const N: usize> WriteXDR for Vec<u8, N> {
28 fn write_xdr<F, W: Writer<F>>(&self, w: &mut W) -> WriteResult<()> {
29 let () = ValidU32::<N>::OK;
30
31 w.write_opaque_variable(self.as_slice())
32 }
33
34 unsafe fn write_xdr_unchecked<F, W: WriterUnchecked<F>>(&self, w: &mut W) {
35 let () = ValidU32::<N>::OK;
36
37 unsafe { w.write_opaque_variable(self.as_slice()) }
40 }
41}
42
43impl<'r, T, const N: usize> ReadXDR<'r> for Vec<T, N>
44where
45 T: ReadXDR<'r>,
46{
47 fn read_xdr<R: Reader<'r>>(r: &mut R) -> ReadResult<Self> {
48 let () = ValidU32::<N>::OK;
49
50 let len = r.read_u32()? as usize;
51 if len > N {
52 return Err(ReadError::max_length_exceeded());
53 }
54
55 let mut vec = Vec::new();
56 for _ in 0..len {
57 vec.push(<T as ReadXDR>::read_xdr(r)?)
58 .map_err(|_| ReadError::max_length_exceeded())?;
59 }
60
61 Ok(vec)
62 }
63}
64
65impl<T, const N: usize> WriteXDR for Vec<T, N>
66where
67 T: WriteXDR,
68{
69 fn write_xdr<F, W: Writer<F>>(&self, w: &mut W) -> WriteResult<()> {
70 let () = ValidU32::<N>::OK;
71
72 w.write_u32(self.len() as u32)?;
73 for elt in self {
74 elt.write_xdr(w)?;
75 }
76 Ok(())
77 }
78
79 unsafe fn write_xdr_unchecked<F, W: WriterUnchecked<F>>(&self, w: &mut W) {
80 let () = ValidU32::<N>::OK;
81
82 unsafe {
85 w.write_u32(self.len() as u32);
86 for elt in self {
87 elt.write_xdr_unchecked(w);
88 }
89 }
90 }
91}
92
93impl<'r, const N: usize> ReadXDR<'r> for String<N> {
94 fn read_xdr<R: Reader<'r>>(r: &mut R) -> ReadResult<Self> {
95 let () = ValidU32::<N>::OK;
96
97 let bytes = r.read_opaque_variable(N as u32)?;
98 let slice = str::from_utf8(bytes).map_err(|_| ReadError::bad_utf8())?;
99
100 let mut s = String::new();
101 s.push_str(slice)
102 .map_err(|_| ReadError::max_length_exceeded())?;
103
104 Ok(s)
105 }
106}
107
108impl<const N: usize> WriteXDR for String<N> {
109 fn write_xdr<F, W: Writer<F>>(&self, w: &mut W) -> WriteResult<()> {
110 let () = ValidU32::<N>::OK;
111
112 w.write_opaque_variable(self.as_bytes())
113 }
114
115 unsafe fn write_xdr_unchecked<F, W: WriterUnchecked<F>>(&self, w: &mut W) {
116 let () = ValidU32::<N>::OK;
117
118 unsafe { w.write_opaque_variable(self.as_bytes()) }
121 }
122}
123
124impl<const N: usize> cxs::ConstMaxSize for Vec<u8, N> {
139 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
140 None
141 } else {
142 cxs::const_writer::max_size_opaque_variable(N as u32)
143 };
144}
145
146impl<T: cxs::ConstMaxSize, const N: usize> cxs::ConstMaxSize for Vec<T, N> {
147 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
148 None
149 } else {
150 cxs::const_writer::max_size_add(
151 Some(cxs::const_writer::size_u32(N as u32)),
152 cxs::const_writer::max_size_array(N, T::MAX_SIZE),
153 )
154 };
155}
156
157impl<const N: usize> cxs::ConstMaxSize for String<N> {
158 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
159 None
160 } else {
161 cxs::const_writer::max_size_opaque_variable(N as u32)
162 };
163}
164
165impl<const N: usize> txs::ConstMaxSize for Vec<u8, N> {
166 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
167 None
168 } else {
169 txs::const_writer::max_size_opaque_variable(N as u32)
170 };
171}
172
173impl<T: txs::ConstMaxSize, const N: usize> txs::ConstMaxSize for Vec<T, N> {
174 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
175 None
176 } else {
177 txs::const_writer::max_size_add(
178 Some(txs::const_writer::size_u32(N as u32)),
179 txs::const_writer::max_size_array(N, T::MAX_SIZE),
180 )
181 };
182}
183
184impl<const N: usize> txs::ConstMaxSize for String<N> {
185 const MAX_SIZE: Option<usize> = if N > u32::MAX as usize {
186 None
187 } else {
188 txs::const_writer::max_size_opaque_variable(N as u32)
189 };
190}