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