rmp/encode/
buffer.rs

1//! Implementation of the [`ByteBuf`] type
2
3use super::RmpWrite;
4use alloc::vec::Vec;
5#[cfg(not(feature = "std"))]
6use core::fmt::{self, Display, Formatter};
7
8/// An error returned from writing to `&mut [u8]` (a byte buffer of fixed capacity) on no_std
9///
10/// In feature="std", capacity overflow in `<&mut [u8] as std::io::Write>::write_exact()`
11/// currently returns [`ErrorKind::WriteZero`](https://doc.rust-lang.org/std/io/enum.ErrorKind.html#variant.WriteZero).
12///
13/// Since no_std doesn't have std::io::Error we use this instead ;)
14///
15/// This is specific to `#[cfg(not(feature = "std"))]` so it is `#[doc(hidden)]`
16#[derive(Debug)]
17#[cfg(not(feature = "std"))]
18#[doc(hidden)]
19pub struct FixedBufCapacityOverflow {
20    _priv: (),
21}
22
23/// An error returned from writing to `&mut [u8]`
24///
25/// Aliased for compatibility with `no_std` mode.
26#[cfg(feature = "std")]
27#[doc(hidden)]
28pub type FixedBufCapacityOverflow = std::io::Error;
29
30#[cfg(not(feature = "std"))]
31impl Display for FixedBufCapacityOverflow {
32    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
33        // This is intentionally vauge because std::io::Error is
34        // Doesn't make sense for no_std to have bettetr errors than std
35        f.write_str("Capacity overflow for fixed-size byte buffer")
36    }
37}
38#[cfg(not(feature = "std"))]
39impl crate::encode::RmpWriteErr for FixedBufCapacityOverflow {}
40
41/// Fallback implementation for fixed-capacity buffers
42///
43/// Only needed for no-std because we don't have
44/// the blanket impl for `std::io::Write`
45#[cfg(not(feature = "std"))]
46impl<'a> RmpWrite for &'a mut [u8] {
47    type Error = FixedBufCapacityOverflow;
48
49    #[inline]
50    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
51        let to_write = buf.len();
52        let remaining = self.len();
53        if to_write <= remaining {
54            self[..to_write].copy_from_slice(buf);
55            unsafe {
56                //Cant use split_at or re-borrowing due to lifetime errors :(
57                *self = core::slice::from_raw_parts_mut(
58                    self.as_mut_ptr().add(to_write),
59                    remaining - to_write,
60                )
61            }
62            Ok(())
63        } else {
64            Err(FixedBufCapacityOverflow { _priv: () })
65        }
66    }
67}
68
69/// A wrapper around `Vec<u8>` to serialize more efficiently.
70///
71/// This has a specialized implementation of `RmpWrite`
72/// It gives `std::convert::Infailable` for errors.
73/// This is because writing to `Vec<T>` can only fail due to allocation.
74///
75/// This has the additional benefit of working on `#[no_std]`
76///
77/// See also [serde_bytes::ByteBuf](https://docs.rs/serde_bytes/0.11/serde_bytes/struct.ByteBuf.html)
78#[derive(Debug, Clone, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
79pub struct ByteBuf {
80    bytes: Vec<u8>,
81}
82impl ByteBuf {
83    /// Construct a new empty buffer
84    #[inline]
85    #[must_use]
86    pub fn new() -> Self {
87        ByteBuf { bytes: Vec::new() }
88    }
89    /// Construct a new buffer with the specified capacity
90    ///
91    /// See [`Vec::with_capacity`] for details
92    #[inline]
93    #[must_use]
94    pub fn with_capacity(capacity: usize) -> Self {
95        ByteBuf {
96            bytes: Vec::with_capacity(capacity),
97        }
98    }
99    /// Unwrap the underlying buffer of this vector
100    #[inline]
101    #[must_use]
102    pub fn into_vec(self) -> Vec<u8> {
103        self.bytes
104    }
105    /// Wrap the specified vector as a [`ByteBuf`]
106    #[inline]
107    #[must_use]
108    pub fn from_vec(bytes: Vec<u8>) -> Self {
109        ByteBuf { bytes }
110    }
111    /// Get a reference to this type as a [Vec]
112    #[inline]
113    #[must_use]
114    pub fn as_vec(&self) -> &Vec<u8> {
115        &self.bytes
116    }
117    /// Get a mutable reference to this type as a [Vec]
118    #[inline]
119    pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
120        &mut self.bytes
121    }
122    /// Get a reference to this type as a slice of bytes (`&[u8]`)
123    #[inline]
124    #[must_use]
125    pub fn as_slice(&self) -> &[u8] {
126        &self.bytes
127    }
128}
129impl AsRef<[u8]> for ByteBuf {
130    fn as_ref(&self) -> &[u8] {
131        &self.bytes
132    }
133}
134impl AsRef<Vec<u8>> for ByteBuf {
135    #[inline]
136    fn as_ref(&self) -> &Vec<u8> {
137        &self.bytes
138    }
139}
140impl AsMut<Vec<u8>> for ByteBuf {
141    #[inline]
142    fn as_mut(&mut self) -> &mut Vec<u8> {
143        &mut self.bytes
144    }
145}
146impl From<ByteBuf> for Vec<u8> {
147    #[inline]
148    fn from(buf: ByteBuf) -> Self {
149        buf.bytes
150    }
151}
152impl From<Vec<u8>> for ByteBuf {
153    #[inline]
154    fn from(bytes: Vec<u8>) -> Self {
155        ByteBuf { bytes }
156    }
157}
158
159impl RmpWrite for ByteBuf {
160    type Error = core::convert::Infallible;
161
162    #[inline]
163    fn write_u8(&mut self, val: u8) -> Result<(), Self::Error> {
164        self.bytes.push(val);
165        Ok(())
166    }
167
168    #[inline]
169    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
170        self.bytes.extend_from_slice(buf);
171        Ok(())
172    }
173}
174#[cfg(not(feature = "std"))]
175impl<'a> RmpWrite for Vec<u8> {
176    type Error = core::convert::Infallible;
177
178    #[inline]
179    fn write_u8(&mut self, val: u8) -> Result<(), Self::Error> {
180        self.push(val);
181        Ok(())
182    }
183
184    #[inline]
185    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
186        self.extend_from_slice(buf);
187        Ok(())
188    }
189}