commonware_utils/array/
mod.rs

1use crate::SizedSerialize;
2use bytes::Buf;
3use std::{
4    cmp::{Ord, PartialOrd},
5    error::Error as StdError,
6    fmt::{Debug, Display},
7    hash::Hash,
8    ops::Deref,
9};
10use thiserror::Error;
11
12pub mod u64;
13pub use u64::U64;
14
15/// Errors returned by the `Array` trait's functions.
16#[derive(Error, Debug, PartialEq)]
17pub enum Error<E: StdError + Send + Sync + 'static> {
18    #[error("invalid bytes")]
19    InsufficientBytes,
20    #[error("other: {0}")]
21    Other(E),
22}
23
24/// Types that can be fallibly read from a fixed-size byte sequence.
25///
26/// `Array` is typically used to parse things like `PublicKeys` and `Signatures`
27/// from an untrusted network connection. Once parsed, these types are assumed
28/// to be well-formed (which prevents duplicate validation).
29///
30/// If a byte sequencer is not properly formatted, `TryFrom` must return an error.
31pub trait Array:
32    Clone
33    + Send
34    + Sync
35    + 'static
36    + Eq
37    + PartialEq
38    + Ord
39    + PartialOrd
40    + Debug
41    + Hash
42    + Display
43    + AsRef<[u8]>
44    + Deref<Target = [u8]>
45    + for<'a> TryFrom<&'a [u8], Error = <Self as Array>::Error>
46    + for<'a> TryFrom<&'a Vec<u8>, Error = <Self as Array>::Error>
47    + TryFrom<Vec<u8>, Error = <Self as Array>::Error>
48    + SizedSerialize
49{
50    /// Errors returned when parsing an invalid byte sequence.
51    type Error: StdError + Send + Sync + 'static;
52
53    /// Attempts to read an array from the provided buffer.
54    fn read_from<B: Buf>(buf: &mut B) -> Result<Self, Error<<Self as Array>::Error>> {
55        let len = Self::SERIALIZED_LEN;
56        if buf.remaining() < len {
57            return Err(Error::InsufficientBytes);
58        }
59
60        let chunk = buf.chunk();
61        if chunk.len() >= len {
62            let array = Self::try_from(&chunk[..len]).map_err(Error::Other)?;
63            buf.advance(len);
64            return Ok(array);
65        }
66
67        let mut temp = vec![0u8; len];
68        buf.copy_to_slice(&mut temp);
69        Self::try_from(temp).map_err(Error::Other)
70    }
71}