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<const CAP: usize> SerWrite for heapless::Vec<u8, CAP> {
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 = "smallvec")]
116#[cfg_attr(docsrs, doc(cfg(feature = "smallvec")))]
117impl From<smallvec::CollectionAllocErr> for SerError {
118    fn from(_err: smallvec::CollectionAllocErr) -> SerError {
119        SerError::BufferFull
120    }
121}
122
123#[cfg(feature = "smallvec")]
124#[cfg_attr(docsrs, doc(cfg(feature = "smallvec")))]
125impl<const CAP: usize> SerWrite for smallvec::SmallVec<[u8; CAP]>
126    where [u8; CAP]: smallvec::Array<Item=u8>,
127{
128    type Error = SerError;
129
130    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
131        self.try_reserve(buf.len())?;
132        self.extend_from_slice(buf);
133        Ok(())
134    }
135    #[inline]
136    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
137        self.try_reserve(1)?;
138        self.push(byte);
139        Ok(())
140    }
141}
142
143#[cfg(feature = "tinyvec")]
144macro_rules! implement_tinyvec_write {
145    () => {
146        fn write(&mut self, buf: &[u8]) -> SerResult<()> {
147            let add_len = buf.len();
148            if add_len == 0 {
149                return Ok(())
150            }
151            if let Some(target) = self.grab_spare_slice_mut().get_mut(..add_len) {
152                target.clone_from_slice(buf);
153                self.set_len(self.len() + add_len);
154                Ok(())
155            }
156            else {
157                Err(SerError::BufferFull)
158            }
159        }
160    };
161}
162
163#[cfg(feature = "tinyvec")]
164#[cfg_attr(docsrs, doc(cfg(feature = "tinyvec")))]
165impl<const CAP: usize> SerWrite for tinyvec::ArrayVec<[u8; CAP]>
166    where [u8; CAP]: tinyvec::Array<Item=u8>,
167{
168    type Error = SerError;
169
170    implement_tinyvec_write!{}
171
172    #[inline]
173    fn write_byte(&mut self, byte: u8) -> SerResult<()> {
174        if self.try_push(byte).is_none() {
175            Ok(())
176        }
177        else {
178            Err(SerError::BufferFull)
179        }
180    }
181}
182
183#[cfg(feature = "tinyvec")]
184#[cfg_attr(docsrs, doc(cfg(feature = "tinyvec")))]
185impl SerWrite for tinyvec::SliceVec<'_, u8> {
186    type Error = SerError;
187
188    implement_tinyvec_write!{}
189}
190
191#[cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))]
192#[cfg_attr(docsrs, doc(cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))))]
193impl<const CAP: usize> SerWrite for tinyvec::TinyVec<[u8; CAP]>
194    where [u8; CAP]: tinyvec::Array<Item=u8>
195{
196    type Error = SerError;
197
198    fn write(&mut self, buf: &[u8]) -> SerResult<()> {
199        self.try_reserve(buf.len())?;
200        match self {
201          tinyvec::TinyVec::Inline(a) => a.extend_from_slice(buf),
202          tinyvec::TinyVec::Heap(h) => h.extend_from_slice(buf),
203        }
204        Ok(())
205    }
206}
207
208#[cfg(test)]
209mod tests {
210    #[allow(unused_imports)]
211    use super::*;
212
213    // SAFETY: this is safe only when the provided slice is never read from.
214    #[cfg(any(feature = "std", feature = "alloc"))]
215    unsafe fn oversize_bytes<'a>() -> &'a[u8] {
216        let oversize = usize::try_from(i64::MAX).unwrap();
217        let ptr = core::ptr::NonNull::<u8>::dangling().as_ptr();
218        unsafe { core::slice::from_raw_parts(ptr, oversize) }
219    }
220
221    #[cfg(any(feature = "std", feature = "alloc"))]
222    #[test]
223    fn test_ser_write_vec() {
224        let mut writer = Vec::new();
225        writer.write(b"Hello World!").unwrap();
226        writer.write_byte(b' ').unwrap();
227        writer.write_str("Good Bye!").unwrap();
228        let expected = b"Hello World! Good Bye!";
229        assert_eq!(&writer, expected);
230        unsafe {
231            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
232        }
233    }
234
235    #[cfg(any(feature = "std", feature = "alloc"))]
236    #[test]
237    fn test_ser_write_vec_deque() {
238        let mut writer = VecDeque::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(feature = "std")]
250    #[test]
251    fn test_ser_write_cursor() {
252        let mut writer = Cursor::new([0u8;22]);
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.get_ref(), expected);
258        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
259        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
260        writer.write(b"").unwrap();
261    }
262
263    #[cfg(feature = "arrayvec")]
264    #[test]
265    fn test_ser_write_arrayvec() {
266        let mut writer = arrayvec::ArrayVec::<u8,22>::new();
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.as_slice(), 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 = "heapless")]
278    #[test]
279    fn test_ser_write_heapless() {
280        let mut writer = heapless::Vec::<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 = "smallvec")]
292    #[test]
293    fn test_ser_write_smallvec() {
294        let mut writer = smallvec::SmallVec::<[u8;12]>::new();
295        writer.write(b"Hello World!").unwrap();
296        writer.write_byte(b' ').unwrap();
297        writer.write_str("Good Bye!").unwrap();
298        let expected = b"Hello World! Good Bye!";
299        assert_eq!(writer.as_slice(), expected);
300        unsafe {
301            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
302        }
303    }
304
305    #[cfg(feature = "tinyvec")]
306    #[test]
307    fn test_ser_write_tinyvec_arrayvec() {
308        let mut writer = tinyvec::ArrayVec::<[u8; 22]>::new();
309        writer.write(b"Hello World!").unwrap();
310        writer.write_byte(b' ').unwrap();
311        writer.write_str("Good Bye!").unwrap();
312        let expected = b"Hello World! Good Bye!";
313        assert_eq!(writer.as_slice(), expected);
314        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
315        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
316        writer.write(b"").unwrap();
317    }
318
319    #[cfg(feature = "tinyvec")]
320    #[test]
321    fn test_ser_write_tinyvec_slicevec() {
322        let mut buf = [0u8;22];
323        let mut writer = tinyvec::SliceVec::from_slice_len(&mut buf, 0);
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        assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
330        assert_eq!(writer.write(b" ").unwrap_err(), SerError::BufferFull);
331        writer.write(b"").unwrap();
332    }
333
334    #[cfg(all(feature = "tinyvec", any(feature = "std", feature = "alloc")))]
335    #[test]
336    fn test_ser_write_tinyvec_tinyvec() {
337        let mut writer = tinyvec::TinyVec::<[u8; 12]>::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        unsafe {
344            assert_eq!(writer.write(oversize_bytes()).unwrap_err(), SerError::BufferFull);
345        }
346    }
347}