Skip to main content

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        Self { bytes: Vec::new() }
88    }
89
90    /// Construct a new buffer with the specified capacity
91    ///
92    /// See [`Vec::with_capacity`] for details
93    #[inline]
94    #[must_use]
95    pub fn with_capacity(capacity: usize) -> Self {
96        Self { 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
106    /// Wrap the specified vector as a [`ByteBuf`]
107    #[inline]
108    #[must_use]
109    pub fn from_vec(bytes: Vec<u8>) -> Self {
110        Self { bytes }
111    }
112
113    /// Get a reference to this type as a [Vec]
114    #[inline]
115    #[must_use]
116    pub fn as_vec(&self) -> &Vec<u8> {
117        &self.bytes
118    }
119
120    /// Get a mutable reference to this type as a [Vec]
121    #[inline]
122    pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
123        &mut self.bytes
124    }
125
126    /// Get a reference to this type as a slice of bytes (`&[u8]`)
127    #[inline]
128    #[must_use]
129    pub fn as_slice(&self) -> &[u8] {
130        &self.bytes
131    }
132}
133impl AsRef<[u8]> for ByteBuf {
134    fn as_ref(&self) -> &[u8] {
135        &self.bytes
136    }
137}
138impl AsRef<Vec<u8>> for ByteBuf {
139    #[inline]
140    fn as_ref(&self) -> &Vec<u8> {
141        &self.bytes
142    }
143}
144impl AsMut<Vec<u8>> for ByteBuf {
145    #[inline]
146    fn as_mut(&mut self) -> &mut Vec<u8> {
147        &mut self.bytes
148    }
149}
150impl From<ByteBuf> for Vec<u8> {
151    #[inline]
152    fn from(buf: ByteBuf) -> Self {
153        buf.bytes
154    }
155}
156impl From<Vec<u8>> for ByteBuf {
157    #[inline]
158    fn from(bytes: Vec<u8>) -> Self {
159        Self { bytes }
160    }
161}
162
163impl RmpWrite for ByteBuf {
164    type Error = core::convert::Infallible;
165
166    #[inline]
167    fn write_u8(&mut self, val: u8) -> Result<(), Self::Error> {
168        self.bytes.push(val);
169        Ok(())
170    }
171
172    #[inline]
173    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
174        self.bytes.extend_from_slice(buf);
175        Ok(())
176    }
177}
178#[cfg(not(feature = "std"))]
179impl<'a> RmpWrite for Vec<u8> {
180    type Error = core::convert::Infallible;
181
182    #[inline]
183    fn write_u8(&mut self, val: u8) -> Result<(), Self::Error> {
184        self.push(val);
185        Ok(())
186    }
187
188    #[inline]
189    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
190        self.extend_from_slice(buf);
191        Ok(())
192    }
193}