Skip to main content

ser_write/
foreign.rs

1/// Implementation for foreign types
2#[cfg(feature = "std")]
3use std::{vec::Vec, collections::VecDeque, io::Cursor};
4#[cfg(all(feature = "alloc",not(feature = "std")))]
5use alloc::{vec::Vec, collections::VecDeque};
6
7#[allow(unused_imports)]
8use super::*;
9
10#[cfg(feature = "std")]
11use std::collections::TryReserveError;
12
13#[cfg(all(not(feature = "std"), feature = "alloc"))]
14use alloc::collections::TryReserveError;
15
16#[cfg(any(feature = "std", feature = "alloc"))]
17impl From<TryReserveError> for SerError {
18    fn from(_err: TryReserveError) -> SerError {
19        SerError::BufferFull
20    }
21}
22
23#[cfg(any(feature = "std", feature = "alloc"))]
24#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
25impl SerWrite for Vec<u8> {
26    type Error = SerError;
27
28    #[inline]
29    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
30        self.try_reserve(buf.len())?;
31        self.extend_from_slice(buf);
32        Ok(())
33    }
34    #[inline]
35    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
36        // FIXME: (vec_push_within_capacity #100486)
37        // if let Err(byte) = self.push_within_capacity(byte) {
38        //     self.try_reserve(1)?;
39        //     let _ = vec.push_within_capacity(byte);
40        // }
41        self.try_reserve(1)?;
42        self.push(byte);
43        Ok(())
44    }
45}
46
47#[cfg(any(feature = "std", feature = "alloc"))]
48#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
49impl SerWrite for VecDeque<u8> {
50    type Error = SerError;
51
52    #[inline]
53    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
54        self.try_reserve(buf.len())?;
55        self.extend(buf.iter().copied());
56        Ok(())
57    }
58    #[inline]
59    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
60        self.try_reserve(1)?;
61        self.push_back(byte);
62        Ok(())
63    }
64}
65
66#[cfg(feature = "std")]
67#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
68impl<T> SerWrite for Cursor<T>
69    where Cursor<T>: std::io::Write
70{
71    type Error = SerError;
72
73    #[inline]
74    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
75        std::io::Write::write_all(self, buf).map_err(|_| SerError::BufferFull)
76    }
77}
78
79#[cfg(feature = "arrayvec")]
80#[cfg_attr(docsrs, doc(cfg(feature = "arrayvec")))]
81impl<T> From<arrayvec::CapacityError<T>> for SerError {
82    fn from(_err: arrayvec::CapacityError<T>) -> SerError {
83        SerError::BufferFull
84    }
85}
86
87#[cfg(feature = "arrayvec")]
88#[cfg_attr(docsrs, doc(cfg(feature = "arrayvec")))]
89impl<const CAP: usize> SerWrite for arrayvec::ArrayVec<u8, CAP> {
90    type Error = SerError;
91
92    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
93        self.try_extend_from_slice(buf).map_err(From::from)
94    }
95    #[inline]
96    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
97        self.try_push(byte).map_err(From::from)
98    }
99}
100
101#[cfg(feature = "heapless")]
102#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
103impl<LenT: heapless::LenType, const CAP: usize> SerWrite for heapless::Vec<u8, CAP, LenT> {
104    type Error = SerError;
105
106    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
107        self.extend_from_slice(buf).map_err(|_| SerError::BufferFull)
108    }
109    #[inline]
110    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
111        self.push(byte).map_err(|_| SerError::BufferFull)
112    }
113}
114
115#[cfg(feature = "heapless")]
116#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
117impl<LenT: heapless::LenType> SerWrite for heapless::VecView<u8, LenT> {
118    type Error = SerError;
119
120    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
121        self.extend_from_slice(buf).map_err(|_| SerError::BufferFull)
122    }
123    #[inline]
124    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
125        self.push(byte).map_err(|_| SerError::BufferFull)
126    }
127}
128
129#[cfg(feature = "smallvec")]
130#[cfg_attr(docsrs, doc(cfg(feature = "smallvec")))]
131impl From<smallvec::CollectionAllocErr> for SerError {
132    fn from(_err: smallvec::CollectionAllocErr) -> SerError {
133        SerError::BufferFull
134    }
135}
136
137#[cfg(feature = "smallvec")]
138#[cfg_attr(docsrs, doc(cfg(feature = "smallvec")))]
139impl<const CAP: usize> SerWrite for smallvec::SmallVec<[u8; CAP]>
140    where [u8; CAP]: smallvec::Array<Item=u8>,
141{
142    type Error = SerError;
143
144    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
145        self.try_reserve(buf.len())?;
146        self.extend_from_slice(buf);
147        Ok(())
148    }
149    #[inline]
150    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
151        self.try_reserve(1)?;
152        self.push(byte);
153        Ok(())
154    }
155}
156
157#[cfg(feature = "tinyvec")]
158macro_rules! implement_tinyvec_write {
159    () => {
160        fn write(&mut self, buf: &[u8]) -> SerResult<()> {
161            let add_len = buf.len();
162            if add_len == 0 {
163                return Ok(())
164            }
165            if let Some(target) = self.grab_spare_slice_mut().get_mut(..add_len) {
166                target.clone_from_slice(buf);
167                self.set_len(self.len() + add_len);
168                Ok(())
169            }
170            else {
171                Err(SerError::BufferFull)
172            }
173        }
174    };
175}
176
177#[cfg(feature = "tinyvec")]
178#[cfg_attr(docsrs, doc(cfg(feature = "tinyvec")))]
179impl<const CAP: usize> SerWrite for tinyvec::ArrayVec<[u8; CAP]>
180    where [u8; CAP]: tinyvec::Array<Item=u8>,
181{
182    type Error = SerError;
183
184    implement_tinyvec_write!{}
185
186    #[inline]
187    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
188        if self.try_push(byte).is_none() {
189            Ok(())
190        }
191        else {
192            Err(SerError::BufferFull)
193        }
194    }
195}
196
197#[cfg(feature = "tinyvec")]
198#[cfg_attr(docsrs, doc(cfg(feature = "tinyvec")))]
199impl SerWrite for tinyvec::SliceVec<'_, u8> {
200    type Error = SerError;
201
202    implement_tinyvec_write!{}
203}
204
205#[cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))]
206#[cfg_attr(docsrs, doc(cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))))]
207impl<const CAP: usize> SerWrite for tinyvec::TinyVec<[u8; CAP]>
208    where [u8; CAP]: tinyvec::Array<Item=u8>
209{
210    type Error = SerError;
211
212    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
213        self.try_reserve(buf.len())?;
214        match self {
215          tinyvec::TinyVec::Inline(a) => a.extend_from_slice(buf),
216          tinyvec::TinyVec::Heap(h) => h.extend_from_slice(buf),
217        }
218        Ok(())
219    }
220}
221
222#[cfg(test)]
223mod tests {
224    #[allow(unused_imports)]
225    use super::*;
226
227    // SAFETY: this is safe only when the provided slice is never read from.
228    #[cfg(any(feature = "std", feature = "alloc"))]
229    unsafe fn oversize_bytes<'a>() -> &'a[u8] {
230        let oversize = usize::try_from(i64::MAX).unwrap();
231        let ptr = core::ptr::NonNull::<u8>::dangling().as_ptr();
232        unsafe { core::slice::from_raw_parts(ptr, oversize) }
233    }
234
235    #[cfg(any(feature = "std", feature = "alloc"))]
236    #[test]
237    fn test_ser_write_vec() {
238        let mut writer = Vec::new();
239        writer.write(b"Hello World!").unwrap();
240        writer.write_byte(b' ').unwrap();
241        writer.write_str("Good Bye!").unwrap();
242        let expected = b"Hello World! Good Bye!";
243        assert_eq!(&writer, expected);
244        unsafe {
245            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
246        }
247    }
248
249    #[cfg(any(feature = "std", feature = "alloc"))]
250    #[test]
251    fn test_ser_write_vec_deque() {
252        let mut writer = VecDeque::new();
253        writer.write(b"Hello World!").unwrap();
254        writer.write_byte(b' ').unwrap();
255        writer.write_str("Good Bye!").unwrap();
256        let expected = b"Hello World! Good Bye!";
257        assert_eq!(&writer, expected);
258        unsafe {
259            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
260        }
261    }
262
263    #[cfg(feature = "std")]
264    #[test]
265    fn test_ser_write_cursor() {
266        let mut writer = Cursor::new([0u8;22]);
267        writer.write(b"Hello World!").unwrap();
268        writer.write_byte(b' ').unwrap();
269        writer.write_str("Good Bye!").unwrap();
270        let expected = b"Hello World! Good Bye!";
271        assert_eq!(writer.get_ref(), expected);
272        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
273        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
274        writer.write(b"").unwrap();
275    }
276
277    #[cfg(feature = "arrayvec")]
278    #[test]
279    fn test_ser_write_arrayvec() {
280        let mut writer = arrayvec::ArrayVec::<u8,22>::new();
281        writer.write(b"Hello World!").unwrap();
282        writer.write_byte(b' ').unwrap();
283        writer.write_str("Good Bye!").unwrap();
284        let expected = b"Hello World! Good Bye!";
285        assert_eq!(writer.as_slice(), expected);
286        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
287        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
288        writer.write(b"").unwrap();
289    }
290
291    #[cfg(feature = "heapless")]
292    #[test]
293    fn test_ser_write_heapless() {
294        fn test_ser_write_heapless_impl<T: heapless::LenType>() {
295            let mut writer = heapless::Vec::<u8,22,T>::new();
296            writer.write(b"Hello World!").unwrap();
297            writer.write_byte(b' ').unwrap();
298            writer.write_str("Good Bye!").unwrap();
299            let expected = b"Hello World! Good Bye!";
300            assert_eq!(writer.as_slice(), expected);
301            assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
302            assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
303            writer.write(b"").unwrap();
304
305            let writer: &mut heapless::VecView<u8,T> = &mut heapless::Vec::<u8,22,T>::new();
306            writer.write(b"Hello World!").unwrap();
307            writer.write_byte(b' ').unwrap();
308            writer.write_str("Good Bye!").unwrap();
309            let expected = b"Hello World! Good Bye!";
310            assert_eq!(writer.as_slice(), expected);
311            assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
312            assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
313            writer.write(b"").unwrap();
314        }
315        test_ser_write_heapless_impl::<usize>();
316        test_ser_write_heapless_impl::<u8>();
317        test_ser_write_heapless_impl::<u16>();
318    }
319
320    #[cfg(feature = "smallvec")]
321    #[test]
322    fn test_ser_write_smallvec() {
323        let mut writer = smallvec::SmallVec::<[u8;12]>::new();
324        writer.write(b"Hello World!").unwrap();
325        writer.write_byte(b' ').unwrap();
326        writer.write_str("Good Bye!").unwrap();
327        let expected = b"Hello World! Good Bye!";
328        assert_eq!(writer.as_slice(), expected);
329        unsafe {
330            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
331        }
332    }
333
334    #[cfg(feature = "tinyvec")]
335    #[test]
336    fn test_ser_write_tinyvec_arrayvec() {
337        let mut writer = tinyvec::ArrayVec::<[u8; 22]>::new();
338        writer.write(b"Hello World!").unwrap();
339        writer.write_byte(b' ').unwrap();
340        writer.write_str("Good Bye!").unwrap();
341        let expected = b"Hello World! Good Bye!";
342        assert_eq!(writer.as_slice(), expected);
343        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
344        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
345        writer.write(b"").unwrap();
346    }
347
348    #[cfg(feature = "tinyvec")]
349    #[test]
350    fn test_ser_write_tinyvec_slicevec() {
351        let mut buf = [0u8;22];
352        let mut writer = tinyvec::SliceVec::from_slice_len(&mut buf, 0);
353        writer.write(b"Hello World!").unwrap();
354        writer.write_byte(b' ').unwrap();
355        writer.write_str("Good Bye!").unwrap();
356        let expected = b"Hello World! Good Bye!";
357        assert_eq!(writer.as_slice(), expected);
358        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
359        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
360        writer.write(b"").unwrap();
361    }
362
363    #[cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))]
364    #[test]
365    fn test_ser_write_tinyvec_tinyvec() {
366        let mut writer = tinyvec::TinyVec::<[u8; 12]>::new();
367        writer.write(b"Hello World!").unwrap();
368        writer.write_byte(b' ').unwrap();
369        writer.write_str("Good Bye!").unwrap();
370        let expected = b"Hello World! Good Bye!";
371        assert_eq!(writer.as_slice(), expected);
372        unsafe {
373            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
374        }
375    }
376}