use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FullError<E> {
IndexExhausted,
StorageFull(E),
}
impl<E> FullError<E> {
#[inline]
pub fn as_ref(&self) -> FullError<&E> {
match self {
Self::IndexExhausted => FullError::IndexExhausted,
Self::StorageFull(error) => FullError::StorageFull(error),
}
}
}
impl<E: fmt::Display> fmt::Display for FullError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::IndexExhausted => f.write_str("the keys can not address another slot"),
Self::StorageFull(error) => {
write!(f, "the storage can not make room for another slot: {error}")
}
}
}
}
pub enum InsertError<T, E> {
IndexExhausted(T),
StorageFull(T, E),
}
impl<T, E> InsertError<T, E> {
#[inline]
pub fn into_inner(self) -> T {
match self {
Self::IndexExhausted(value) | Self::StorageFull(value, _) => value,
}
}
#[inline]
pub fn kind(&self) -> FullError<&E> {
match self {
Self::IndexExhausted(_) => FullError::IndexExhausted,
Self::StorageFull(_, error) => FullError::StorageFull(error),
}
}
#[inline]
pub fn into_parts(self) -> (FullError<E>, T) {
match self {
Self::IndexExhausted(value) => (FullError::IndexExhausted, value),
Self::StorageFull(value, error) => (FullError::StorageFull(error), value),
}
}
}
impl<T, E: fmt::Debug> fmt::Debug for InsertError<T, E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::IndexExhausted(_) => f.write_str("IndexExhausted(..)"),
Self::StorageFull(_, error) => write!(f, "StorageFull(.., {error:?})"),
}
}
}
impl<T, E: fmt::Display> fmt::Display for InsertError<T, E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.kind(), f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InsertWithError<E, S> {
Full(FullError<S>),
Rejected(E),
}
impl<E, S> InsertWithError<E, S> {
#[inline]
pub fn flatten(self) -> E
where
E: From<FullError<S>>,
{
match self {
Self::Full(full) => E::from(full),
Self::Rejected(error) => error,
}
}
#[inline]
pub fn rejected(self) -> Option<E> {
match self {
Self::Rejected(error) => Some(error),
Self::Full(_) => None,
}
}
#[inline]
pub fn is_full(&self) -> bool {
matches!(self, Self::Full(_))
}
}
impl<E, S> From<FullError<S>> for InsertWithError<E, S> {
#[inline]
fn from(full: FullError<S>) -> Self {
Self::Full(full)
}
}
impl<E: fmt::Display, S: fmt::Display> fmt::Display for InsertWithError<E, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Full(full) => fmt::Display::fmt(full, f),
Self::Rejected(error) => fmt::Display::fmt(error, f),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GetDisjointMutError {
InvalidKey,
OverlappingKeys,
}
impl fmt::Display for GetDisjointMutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidKey => f.write_str("one of the keys is invalid"),
Self::OverlappingKeys => f.write_str("two of the keys point at the same slot"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GetDisjointMutAtError {
NoValue,
OverlappingIndices,
}
impl fmt::Display for GetDisjointMutAtError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoValue => f.write_str("one of the indices has no value"),
Self::OverlappingIndices => f.write_str("two of the indices are the same"),
}
}
}