casper_types/bytesrepr/
bytes.rs

1use alloc::{
2    string::String,
3    vec::{IntoIter, Vec},
4};
5use core::{
6    cmp, fmt,
7    iter::FromIterator,
8    ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo},
9    slice,
10};
11
12use rand::{
13    distributions::{Distribution, Standard},
14    Rng,
15};
16#[cfg(feature = "json-schema")]
17use schemars::JsonSchema;
18use serde::{
19    de::{Error as SerdeError, SeqAccess, Visitor},
20    Deserialize, Deserializer, Serialize, Serializer,
21};
22
23use super::{Error, FromBytes, ToBytes};
24use crate::{checksummed_hex, CLType, CLTyped};
25
26/// A newtype wrapper for bytes that has efficient serialization routines.
27#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Default, Hash)]
28#[cfg_attr(
29    feature = "json-schema",
30    derive(JsonSchema),
31    schemars(description = "Hex-encoded bytes.")
32)]
33#[rustfmt::skip]
34pub struct Bytes(
35    #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))]
36    Vec<u8>
37);
38
39impl Bytes {
40    /// Constructs a new, empty vector of bytes.
41    pub fn new() -> Bytes {
42        Bytes::default()
43    }
44
45    /// Returns reference to inner container.
46    #[inline]
47    pub fn inner_bytes(&self) -> &Vec<u8> {
48        &self.0
49    }
50
51    /// Extracts a slice containing the entire vector.
52    pub fn as_slice(&self) -> &[u8] {
53        self
54    }
55
56    /// Consumes self and returns the inner bytes.
57    pub fn take_inner(self) -> Vec<u8> {
58        self.0
59    }
60}
61
62impl Deref for Bytes {
63    type Target = [u8];
64
65    fn deref(&self) -> &Self::Target {
66        self.0.deref()
67    }
68}
69
70impl From<Vec<u8>> for Bytes {
71    fn from(vec: Vec<u8>) -> Self {
72        Self(vec)
73    }
74}
75
76impl From<Bytes> for Vec<u8> {
77    fn from(bytes: Bytes) -> Self {
78        bytes.0
79    }
80}
81
82impl From<&[u8]> for Bytes {
83    fn from(bytes: &[u8]) -> Self {
84        Self(bytes.to_vec())
85    }
86}
87
88impl CLTyped for Bytes {
89    fn cl_type() -> CLType {
90        <Vec<u8>>::cl_type()
91    }
92}
93
94impl AsRef<[u8]> for Bytes {
95    fn as_ref(&self) -> &[u8] {
96        self.0.as_ref()
97    }
98}
99
100impl ToBytes for Bytes {
101    #[inline(always)]
102    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
103        super::vec_u8_to_bytes(&self.0)
104    }
105
106    #[inline(always)]
107    fn into_bytes(self) -> Result<Vec<u8>, Error> {
108        super::vec_u8_to_bytes(&self.0)
109    }
110
111    #[inline(always)]
112    fn serialized_length(&self) -> usize {
113        super::vec_u8_serialized_length(&self.0)
114    }
115
116    #[inline(always)]
117    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
118        super::write_u8_slice(self.as_slice(), writer)
119    }
120}
121
122impl FromBytes for Bytes {
123    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), super::Error> {
124        let (size, remainder) = u32::from_bytes(bytes)?;
125        let (result, remainder) = super::safe_split_at(remainder, size as usize)?;
126        Ok((Bytes(result.to_vec()), remainder))
127    }
128
129    fn from_vec(stream: Vec<u8>) -> Result<(Self, Vec<u8>), Error> {
130        let (size, mut stream) = u32::from_vec(stream)?;
131
132        if size as usize > stream.len() {
133            Err(Error::EarlyEndOfStream)
134        } else {
135            let remainder = stream.split_off(size as usize);
136            Ok((Bytes(stream), remainder))
137        }
138    }
139}
140
141impl Index<usize> for Bytes {
142    type Output = u8;
143
144    fn index(&self, index: usize) -> &u8 {
145        let Bytes(ref dat) = self;
146        &dat[index]
147    }
148}
149
150impl Index<Range<usize>> for Bytes {
151    type Output = [u8];
152
153    fn index(&self, index: Range<usize>) -> &[u8] {
154        let Bytes(dat) = self;
155        &dat[index]
156    }
157}
158
159impl Index<RangeTo<usize>> for Bytes {
160    type Output = [u8];
161
162    fn index(&self, index: RangeTo<usize>) -> &[u8] {
163        let Bytes(dat) = self;
164        &dat[index]
165    }
166}
167
168impl Index<RangeFrom<usize>> for Bytes {
169    type Output = [u8];
170
171    fn index(&self, index: RangeFrom<usize>) -> &[u8] {
172        let Bytes(dat) = self;
173        &dat[index]
174    }
175}
176
177impl Index<RangeFull> for Bytes {
178    type Output = [u8];
179
180    fn index(&self, _: RangeFull) -> &[u8] {
181        let Bytes(dat) = self;
182        &dat[..]
183    }
184}
185
186impl FromIterator<u8> for Bytes {
187    #[inline]
188    fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Bytes {
189        let vec = Vec::from_iter(iter);
190        Bytes(vec)
191    }
192}
193
194impl<'a> IntoIterator for &'a Bytes {
195    type Item = &'a u8;
196
197    type IntoIter = slice::Iter<'a, u8>;
198
199    fn into_iter(self) -> Self::IntoIter {
200        self.0.iter()
201    }
202}
203
204impl IntoIterator for Bytes {
205    type Item = u8;
206
207    type IntoIter = IntoIter<u8>;
208
209    fn into_iter(self) -> Self::IntoIter {
210        self.0.into_iter()
211    }
212}
213
214#[cfg(feature = "datasize")]
215impl datasize::DataSize for Bytes {
216    const IS_DYNAMIC: bool = true;
217
218    const STATIC_HEAP_SIZE: usize = 0;
219
220    fn estimate_heap_size(&self) -> usize {
221        self.0.capacity() * size_of::<u8>()
222    }
223}
224
225const RANDOM_BYTES_MAX_LENGTH: usize = 100;
226
227impl Distribution<Bytes> for Standard {
228    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Bytes {
229        let len = rng.gen_range(0..RANDOM_BYTES_MAX_LENGTH);
230        let mut result = Vec::with_capacity(len);
231        for _ in 0..len {
232            result.push(rng.gen());
233        }
234        result.into()
235    }
236}
237
238struct BytesVisitor;
239
240impl<'de> Visitor<'de> for BytesVisitor {
241    type Value = Bytes;
242
243    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
244        formatter.write_str("byte array")
245    }
246
247    fn visit_seq<V>(self, mut visitor: V) -> Result<Bytes, V::Error>
248    where
249        V: SeqAccess<'de>,
250    {
251        let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
252        let mut bytes = Vec::with_capacity(len);
253
254        while let Some(b) = visitor.next_element()? {
255            bytes.push(b);
256        }
257
258        Ok(Bytes::from(bytes))
259    }
260
261    fn visit_bytes<E>(self, v: &[u8]) -> Result<Bytes, E>
262    where
263        E: SerdeError,
264    {
265        Ok(Bytes::from(v))
266    }
267
268    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Bytes, E>
269    where
270        E: SerdeError,
271    {
272        Ok(Bytes::from(v))
273    }
274
275    fn visit_str<E>(self, v: &str) -> Result<Bytes, E>
276    where
277        E: SerdeError,
278    {
279        Ok(Bytes::from(v.as_bytes()))
280    }
281
282    fn visit_string<E>(self, v: String) -> Result<Bytes, E>
283    where
284        E: SerdeError,
285    {
286        Ok(Bytes::from(v.into_bytes()))
287    }
288}
289
290impl<'de> Deserialize<'de> for Bytes {
291    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
292    where
293        D: Deserializer<'de>,
294    {
295        if deserializer.is_human_readable() {
296            let hex_string = String::deserialize(deserializer)?;
297            checksummed_hex::decode(hex_string)
298                .map(Bytes)
299                .map_err(SerdeError::custom)
300        } else {
301            let bytes = deserializer.deserialize_byte_buf(BytesVisitor)?;
302            Ok(bytes)
303        }
304    }
305}
306
307impl Serialize for Bytes {
308    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
309    where
310        S: Serializer,
311    {
312        if serializer.is_human_readable() {
313            base16::encode_lower(&self.0).serialize(serializer)
314        } else {
315            serializer.serialize_bytes(&self.0)
316        }
317    }
318}
319
320#[cfg(test)]
321mod tests {
322    use crate::bytesrepr::{self, Error, FromBytes, ToBytes, U32_SERIALIZED_LENGTH};
323    use alloc::vec::Vec;
324
325    use serde_json::json;
326    use serde_test::{assert_tokens, Configure, Token};
327
328    use super::Bytes;
329
330    const TRUTH: &[u8] = &[0xde, 0xad, 0xbe, 0xef];
331
332    #[test]
333    fn vec_u8_from_bytes() {
334        let data: Bytes = vec![1, 2, 3, 4, 5].into();
335        let data_bytes = data.to_bytes().unwrap();
336        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH / 2]).is_err());
337        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH]).is_err());
338        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH + 2]).is_err());
339    }
340
341    #[test]
342    fn should_serialize_deserialize_bytes() {
343        let data: Bytes = vec![1, 2, 3, 4, 5].into();
344        bytesrepr::test_serialization_roundtrip(&data);
345    }
346
347    #[test]
348    fn should_fail_to_serialize_deserialize_malicious_bytes() {
349        let data: Bytes = vec![1, 2, 3, 4, 5].into();
350        let mut serialized = data.to_bytes().expect("should serialize data");
351        serialized = serialized[..serialized.len() - 1].to_vec();
352        let res: Result<(_, &[u8]), Error> = Bytes::from_bytes(&serialized);
353        assert_eq!(res.unwrap_err(), Error::EarlyEndOfStream);
354    }
355
356    #[test]
357    fn should_serialize_deserialize_bytes_and_keep_rem() {
358        let data: Bytes = vec![1, 2, 3, 4, 5].into();
359        let expected_rem: Vec<u8> = vec![6, 7, 8, 9, 10];
360        let mut serialized = data.to_bytes().expect("should serialize data");
361        serialized.extend(&expected_rem);
362        let (deserialized, rem): (Bytes, &[u8]) =
363            FromBytes::from_bytes(&serialized).expect("should deserialize data");
364        assert_eq!(data, deserialized);
365        assert_eq!(&rem, &expected_rem);
366    }
367
368    #[test]
369    fn should_ser_de_human_readable() {
370        let truth = vec![0xde, 0xad, 0xbe, 0xef];
371
372        let bytes_ser: Bytes = truth.clone().into();
373
374        let json_object = serde_json::to_value(bytes_ser).unwrap();
375        assert_eq!(json_object, json!("deadbeef"));
376
377        let bytes_de: Bytes = serde_json::from_value(json_object).unwrap();
378        assert_eq!(bytes_de, Bytes::from(truth));
379    }
380
381    #[test]
382    fn should_ser_de_readable() {
383        let truth: Bytes = TRUTH.into();
384        assert_tokens(&truth.readable(), &[Token::Str("deadbeef")]);
385    }
386
387    #[test]
388    fn should_ser_de_compact() {
389        let truth: Bytes = TRUTH.into();
390        assert_tokens(&truth.compact(), &[Token::Bytes(TRUTH)]);
391    }
392}
393
394#[cfg(test)]
395pub mod gens {
396    use super::Bytes;
397    use proptest::{
398        collection::{vec, SizeRange},
399        prelude::*,
400    };
401
402    pub fn bytes_arb(size: impl Into<SizeRange>) -> impl Strategy<Value = Bytes> {
403        vec(any::<u8>(), size).prop_map(Bytes::from)
404    }
405}