Collect errors into a single error
This commit is contained in:
parent
2b7d5560ad
commit
c8c5c8ff16
@ -1,4 +1,4 @@
|
|||||||
use crate::FixedSizedError;
|
use crate::Error;
|
||||||
use bit_reverse::LookupReverse;
|
use bit_reverse::LookupReverse;
|
||||||
use bit_vec::BitVec as Bitfield;
|
use bit_vec::BitVec as Bitfield;
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
@ -12,10 +12,10 @@ use typenum::Unsigned;
|
|||||||
|
|
||||||
/// Provides a common `impl` for structs that wrap a `$name`.
|
/// Provides a common `impl` for structs that wrap a `$name`.
|
||||||
macro_rules! common_impl {
|
macro_rules! common_impl {
|
||||||
($name: ident, $error: ident) => {
|
($name: ident) => {
|
||||||
impl<N: Unsigned> $name<N> {
|
impl<N: Unsigned> $name<N> {
|
||||||
/// Create a new BitList list with `initial_len` bits all set to `false`.
|
/// Create a new BitList list with `initial_len` bits all set to `false`.
|
||||||
pub fn with_capacity(initial_len: usize) -> Result<Self, $error> {
|
pub fn with_capacity(initial_len: usize) -> Result<Self, Error> {
|
||||||
Self::from_elem(initial_len, false)
|
Self::from_elem(initial_len, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ macro_rules! common_impl {
|
|||||||
///
|
///
|
||||||
/// Note: if `initial_len` is not a multiple of 8, the remaining bits will be set to `false`
|
/// Note: if `initial_len` is not a multiple of 8, the remaining bits will be set to `false`
|
||||||
/// regardless of `bit`.
|
/// regardless of `bit`.
|
||||||
pub fn from_elem(initial_len: usize, bit: bool) -> Result<Self, $error> {
|
pub fn from_elem(initial_len: usize, bit: bool) -> Result<Self, Error> {
|
||||||
// BitVec can panic if we don't set the len to be a multiple of 8.
|
// BitVec can panic if we don't set the len to be a multiple of 8.
|
||||||
let full_len = ((initial_len + 7) / 8) * 8;
|
let full_len = ((initial_len + 7) / 8) * 8;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ macro_rules! common_impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bitfield using the supplied `bytes` as input
|
/// Create a new bitfield using the supplied `bytes` as input
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, $error> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
Self::validate_length(bytes.len().saturating_mul(8))?;
|
Self::validate_length(bytes.len().saturating_mul(8))?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -62,17 +62,17 @@ macro_rules! common_impl {
|
|||||||
/// If the index is in bounds, then result is Ok(value) where value is `true` if the
|
/// If the index is in bounds, then result is Ok(value) where value is `true` if the
|
||||||
/// bit is 1 and `false` if the bit is 0. If the index is out of bounds, we return an
|
/// bit is 1 and `false` if the bit is 0. If the index is out of bounds, we return an
|
||||||
/// error to that extent.
|
/// error to that extent.
|
||||||
pub fn get(&self, i: usize) -> Result<bool, $error> {
|
pub fn get(&self, i: usize) -> Result<bool, Error> {
|
||||||
if i < N::to_usize() {
|
if i < N::to_usize() {
|
||||||
match self.bitfield.get(i) {
|
match self.bitfield.get(i) {
|
||||||
Some(value) => Ok(value),
|
Some(value) => Ok(value),
|
||||||
None => Err($error::OutOfBounds {
|
None => Err(Error::OutOfBounds {
|
||||||
i,
|
i,
|
||||||
len: self.bitfield.len(),
|
len: self.bitfield.len(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err($error::InvalidLength {
|
Err(Error::InvalidLength {
|
||||||
i,
|
i,
|
||||||
len: N::to_usize(),
|
len: N::to_usize(),
|
||||||
})
|
})
|
||||||
@ -83,10 +83,10 @@ macro_rules! common_impl {
|
|||||||
///
|
///
|
||||||
/// If the index is out of bounds, we expand the size of the underlying set to include
|
/// If the index is out of bounds, we expand the size of the underlying set to include
|
||||||
/// the new index. Returns the previous value if there was one.
|
/// the new index. Returns the previous value if there was one.
|
||||||
pub fn set(&mut self, i: usize, value: bool) -> Result<(), $error> {
|
pub fn set(&mut self, i: usize, value: bool) -> Result<(), Error> {
|
||||||
match self.get(i) {
|
match self.get(i) {
|
||||||
Ok(previous) => Some(previous),
|
Ok(previous) => Some(previous),
|
||||||
Err($error::OutOfBounds { len, .. }) => {
|
Err(Error::OutOfBounds { len, .. }) => {
|
||||||
let new_len = i - len + 1;
|
let new_len = i - len + 1;
|
||||||
self.bitfield.grow(new_len, false);
|
self.bitfield.grow(new_len, false);
|
||||||
None
|
None
|
||||||
@ -266,7 +266,7 @@ pub struct BitVector<N> {
|
|||||||
_phantom: PhantomData<N>,
|
_phantom: PhantomData<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
common_impl!(BitVector, FixedSizedError);
|
common_impl!(BitVector);
|
||||||
|
|
||||||
impl<N: Unsigned> BitVector<N> {
|
impl<N: Unsigned> BitVector<N> {
|
||||||
/// Create a new bitfield.
|
/// Create a new bitfield.
|
||||||
@ -278,11 +278,11 @@ impl<N: Unsigned> BitVector<N> {
|
|||||||
N::to_usize()
|
N::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_length(len: usize) -> Result<(), FixedSizedError> {
|
fn validate_length(len: usize) -> Result<(), Error> {
|
||||||
let fixed_len = N::to_usize();
|
let fixed_len = N::to_usize();
|
||||||
|
|
||||||
if len > fixed_len {
|
if len > fixed_len {
|
||||||
Err(FixedSizedError::InvalidLength {
|
Err(Error::InvalidLength {
|
||||||
i: len,
|
i: len,
|
||||||
len: fixed_len,
|
len: fixed_len,
|
||||||
})
|
})
|
||||||
@ -329,7 +329,7 @@ pub struct BitList<N> {
|
|||||||
_phantom: PhantomData<N>,
|
_phantom: PhantomData<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
common_impl!(BitList, FixedSizedError);
|
common_impl!(BitList);
|
||||||
|
|
||||||
impl<N: Unsigned> BitList<N> {
|
impl<N: Unsigned> BitList<N> {
|
||||||
/// Create a new, empty BitList.
|
/// Create a new, empty BitList.
|
||||||
@ -340,11 +340,11 @@ impl<N: Unsigned> BitList<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_length(len: usize) -> Result<(), FixedSizedError> {
|
fn validate_length(len: usize) -> Result<(), Error> {
|
||||||
let max_len = Self::max_len();
|
let max_len = Self::max_len();
|
||||||
|
|
||||||
if len > max_len {
|
if len > max_len {
|
||||||
Err(FixedSizedError::InvalidLength {
|
Err(Error::InvalidLength {
|
||||||
i: len,
|
i: len,
|
||||||
len: max_len,
|
len: max_len,
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::FixedSizedError as Error;
|
use crate::Error;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Deref, Index, IndexMut};
|
use std::ops::{Deref, Index, IndexMut};
|
||||||
|
@ -7,30 +7,9 @@ pub use fixed_vector::FixedVector;
|
|||||||
pub use typenum;
|
pub use typenum;
|
||||||
pub use variable_list::VariableList;
|
pub use variable_list::VariableList;
|
||||||
|
|
||||||
/// Returned when a variable-length item encounters an error.
|
/// Returned when an item encounters an error.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum VariableSizedError {
|
pub enum Error {
|
||||||
/// The operation would cause the maximum length to be exceeded.
|
InvalidLength { i: usize, len: usize },
|
||||||
ExceedsMaxLength {
|
OutOfBounds { i: usize, len: usize },
|
||||||
len: usize,
|
|
||||||
max_len: usize,
|
|
||||||
},
|
|
||||||
OutOfBounds {
|
|
||||||
i: usize,
|
|
||||||
len: usize,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returned when a fixed-length item encounters an error.
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub enum FixedSizedError {
|
|
||||||
/// The operation would create an item of an invalid size.
|
|
||||||
InvalidLength {
|
|
||||||
i: usize,
|
|
||||||
len: usize,
|
|
||||||
},
|
|
||||||
OutOfBounds {
|
|
||||||
i: usize,
|
|
||||||
len: usize,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::VariableSizedError as Error;
|
use crate::Error;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Deref, Index, IndexMut};
|
use std::ops::{Deref, Index, IndexMut};
|
||||||
@ -61,9 +61,9 @@ impl<T, N: Unsigned> VariableList<T, N> {
|
|||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ExceedsMaxLength {
|
Err(Error::InvalidLength {
|
||||||
len: vec.len(),
|
i: vec.len(),
|
||||||
max_len: Self::max_len(),
|
len: Self::max_len(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,9 +90,9 @@ impl<T, N: Unsigned> VariableList<T, N> {
|
|||||||
if self.vec.len() < Self::max_len() {
|
if self.vec.len() < Self::max_len() {
|
||||||
Ok(self.vec.push(value))
|
Ok(self.vec.push(value))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ExceedsMaxLength {
|
Err(Error::InvalidLength {
|
||||||
len: self.vec.len() + 1,
|
i: self.vec.len() + 1,
|
||||||
max_len: Self::max_len(),
|
len: Self::max_len(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user