commonware_utils/array/
mod.rs

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