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#[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 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
147impl 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}