Skip to main content

bilrost/
types.rs

1use alloc::borrow::Cow;
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4use core::borrow::{Borrow, BorrowMut};
5use core::ops::{Deref, DerefMut};
6
7use bytes::{Buf, BufMut};
8
9use crate::buf::ReverseBuf;
10use crate::encoding::{
11    skip_field, Canonicity, Capped, DecodeContext, RawDistinguishedMessageBorrowDecoder,
12    RawDistinguishedMessageDecoder, RawMessage, RawMessageBorrowDecoder, RawMessageDecoder,
13    RestrictedDecodeContext, WireType,
14};
15use crate::DecodeError;
16
17/// Newtype wrapper to act as a simple "bytes data" type in Bilrost. It transparently wraps a
18/// `Vec<u8>` and is fully supported by the `General` encoder.
19///
20/// To use `Vec<u8>` directly, use the `PlainBytes` encoder.
21#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
22#[repr(transparent)]
23pub struct Blob(Vec<u8>);
24
25impl Blob {
26    pub fn new() -> Self {
27        Self::from_vec(Vec::new())
28    }
29
30    pub fn from_vec(vec: Vec<u8>) -> Self {
31        Self(vec)
32    }
33
34    pub fn into_inner(self) -> Vec<u8> {
35        self.0
36    }
37}
38
39impl Deref for Blob {
40    type Target = Vec<u8>;
41
42    fn deref(&self) -> &Self::Target {
43        &self.0
44    }
45}
46
47impl DerefMut for Blob {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        &mut self.0
50    }
51}
52
53impl AsRef<Vec<u8>> for Blob {
54    fn as_ref(&self) -> &Vec<u8> {
55        &self.0
56    }
57}
58
59impl AsMut<Vec<u8>> for Blob {
60    fn as_mut(&mut self) -> &mut Vec<u8> {
61        &mut self.0
62    }
63}
64
65impl Borrow<Vec<u8>> for Blob {
66    fn borrow(&self) -> &Vec<u8> {
67        &self.0
68    }
69}
70
71impl BorrowMut<Vec<u8>> for Blob {
72    fn borrow_mut(&mut self) -> &mut Vec<u8> {
73        &mut self.0
74    }
75}
76
77impl From<Vec<u8>> for Blob {
78    fn from(value: Vec<u8>) -> Self {
79        Blob::from_vec(value)
80    }
81}
82
83impl From<Blob> for Vec<u8> {
84    fn from(value: Blob) -> Self {
85        value.0
86    }
87}
88
89impl From<&[u8]> for Blob {
90    fn from(value: &[u8]) -> Self {
91        Self(value.into())
92    }
93}
94
95impl From<&mut [u8]> for Blob {
96    fn from(value: &mut [u8]) -> Self {
97        Self(value.into())
98    }
99}
100
101impl<const N: usize> From<&[u8; N]> for Blob {
102    fn from(value: &[u8; N]) -> Self {
103        // MSRV: as_slice() needed
104        Self(value.as_slice().into())
105    }
106}
107
108impl<const N: usize> From<[u8; N]> for Blob {
109    fn from(value: [u8; N]) -> Self {
110        Self(value.into())
111    }
112}
113
114impl From<Cow<'_, [u8]>> for Blob {
115    fn from(value: Cow<[u8]>) -> Self {
116        Self(value.into())
117    }
118}
119
120impl From<Box<[u8]>> for Blob {
121    fn from(value: Box<[u8]>) -> Self {
122        Self(value.into())
123    }
124}
125
126impl From<&str> for Blob {
127    fn from(value: &str) -> Self {
128        Self(value.into())
129    }
130}
131
132#[cfg(test)]
133impl proptest::arbitrary::Arbitrary for Blob {
134    type Parameters = <Vec<u8> as proptest::arbitrary::Arbitrary>::Parameters;
135    fn arbitrary_with(top: Self::Parameters) -> Self::Strategy {
136        proptest::strategy::Strategy::prop_map(
137            proptest::arbitrary::any_with::<Vec<u8>>(top),
138            Blob::from_vec,
139        )
140    }
141    type Strategy = proptest::strategy::Map<
142        <Vec<u8> as proptest::arbitrary::Arbitrary>::Strategy,
143        fn(Vec<u8>) -> Self,
144    >;
145}
146
147/// The empty tuple unit is the only native tuple type that implements Message because there are no
148/// choices to be made about how its fields will be encoded. All other native tuples are only
149/// implemented as field values. They encode exactly as if they were nested messages, but their
150/// encoding must be specified.
151impl RawMessage for () {
152    const __ASSERTIONS: () = ();
153
154    fn raw_encode<B: BufMut + ?Sized>(&self, _buf: &mut B) {}
155
156    fn raw_prepend<B: ReverseBuf + ?Sized>(&self, _buf: &mut B) {}
157
158    fn raw_encoded_len(&self) -> usize {
159        0
160    }
161}
162
163impl RawMessageDecoder for () {
164    fn raw_decode_field<B: Buf + ?Sized>(
165        &mut self,
166        _tag: u32,
167        wire_type: WireType,
168        _duplicated: bool,
169        buf: Capped<B>,
170        _ctx: DecodeContext,
171    ) -> Result<(), DecodeError>
172    where
173        Self: Sized,
174    {
175        skip_field(wire_type, buf)
176    }
177}
178
179impl RawDistinguishedMessageDecoder for () {
180    fn raw_decode_field_distinguished<B: Buf + ?Sized>(
181        &mut self,
182        _tag: u32,
183        wire_type: WireType,
184        _duplicated: bool,
185        buf: Capped<B>,
186        ctx: RestrictedDecodeContext,
187    ) -> Result<Canonicity, DecodeError>
188    where
189        Self: Sized,
190    {
191        _ = ctx.check(Canonicity::HasExtensions)?;
192        skip_field(wire_type, buf)?;
193        Ok(Canonicity::HasExtensions)
194    }
195}
196
197impl RawMessageBorrowDecoder<'_> for () {
198    fn raw_borrow_decode_field(
199        &mut self,
200        _tag: u32,
201        wire_type: WireType,
202        _duplicated: bool,
203        buf: Capped<&'_ [u8]>,
204        _ctx: DecodeContext,
205    ) -> Result<(), DecodeError> {
206        skip_field(wire_type, buf)
207    }
208}
209
210impl RawDistinguishedMessageBorrowDecoder<'_> for () {
211    fn raw_borrow_decode_field_distinguished(
212        &mut self,
213        _tag: u32,
214        wire_type: WireType,
215        _duplicated: bool,
216        buf: Capped<&'_ [u8]>,
217        ctx: RestrictedDecodeContext,
218    ) -> Result<Canonicity, DecodeError> {
219        _ = ctx.check(Canonicity::HasExtensions)?;
220        skip_field(wire_type, buf)?;
221        Ok(Canonicity::HasExtensions)
222    }
223}