falco_event/fields/from_bytes.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use thiserror::Error;
/// Error type for deserializing data from a byte buffer
#[derive(Error, Debug)]
pub enum FromBytesError {
/// I/O error
#[error("I/O error")]
IoError(#[from] std::io::Error),
/// Required field not found
#[error("required field not found")]
RequiredFieldNotFound,
/// NUL inside a string
#[error("internal NUL in string")]
InternalNul,
/// Missing NUL terminator
#[error("missing NUL terminator")]
MissingNul,
/// Truncated field
#[error("truncated field (wanted {wanted}, got {got})")]
TruncatedField {
/// the size we wanted
wanted: usize,
/// the size we got
got: usize,
},
/// Invalid length
#[error("invalid length")]
InvalidLength,
/// Invalid PT_DYN discriminant
#[error("invalid PT_DYN discriminant")]
InvalidDynDiscriminant,
/// Odd item count in pair array
#[error("odd item count in pair array")]
OddPairItemCount,
}
/// The result of a deserialization
pub type FromBytesResult<T> = Result<T, FromBytesError>;
/// Deserialize a field from a byte buffer
pub trait FromBytes<'a>: Sized {
/// Read the binary representation of a field and return the parsed representation
///
/// **Note**: the argument is a mutable reference to an immutable slice. While the contents
/// of the slice cannot be modified, the slice itself can. Every call to `from_bytes` consumes
/// a number of bytes from the beginning of the slice.
fn from_bytes(buf: &mut &'a [u8]) -> FromBytesResult<Self>;
/// Read the binary representation of a field from a buffer that may or may not exist
///
/// The default implementation returns an error when the buffer does not exist, but the blanket
/// impl for `Option<T>` effectively returns `Ok(None)`
fn from_maybe_bytes(buf: Option<&mut &'a [u8]>) -> FromBytesResult<Self> {
match buf {
Some(buf) => Self::from_bytes(buf),
None => Err(FromBytesError::RequiredFieldNotFound),
}
}
}
impl<'a, T: FromBytes<'a> + 'a> FromBytes<'a> for Option<T>
where
T: Sized,
{
fn from_bytes(buf: &mut &'a [u8]) -> FromBytesResult<Self> {
T::from_bytes(buf).map(Some)
}
fn from_maybe_bytes(buf: Option<&mut &'a [u8]>) -> FromBytesResult<Self> {
match buf {
Some([]) => Ok(None),
Some(buf) => Self::from_bytes(buf),
None => Ok(None),
}
}
}