use crate::encoding::implement_core_empty_state_rules;
use crate::{Canonicity, DecodeErrorKind};
pub trait EmptyState<E, T: ?Sized>: ForOverwrite<E, T> {
#[inline(always)]
fn empty() -> T
where
T: Sized,
{
<Self as ForOverwrite<E, T>>::for_overwrite()
}
fn is_empty(val: &T) -> bool;
fn clear(val: &mut T);
}
pub trait ForOverwrite<E, T: ?Sized> {
fn for_overwrite() -> T
where
T: Sized;
}
implement_core_empty_state_rules!(());
#[macro_export]
macro_rules! for_overwrite_via_default {
(
$ty:ty
$(, with generics ($($generics:tt)*))?
$(, with where clause ($($where_clause:tt)*))?
) => {
impl<$($($generics)*)?> $crate::encoding::ForOverwrite<(), $ty> for ()
where
$ty: ::core::default::Default,
$($($where_clause)*)?
{
#[inline]
fn for_overwrite() -> $ty {
::core::default::Default::default()
}
}
};
}
pub use for_overwrite_via_default;
#[macro_export]
macro_rules! empty_state_via_for_overwrite {
(
$ty:ty
$(, with generics ($($generics:tt)*))?
$(, with where clause ($($where_clause:tt)*))?
) => {
impl<$($($generics)*)?> $crate::encoding::EmptyState<(), $ty> for ()
where
$ty: ::core::cmp::PartialEq,
(): $crate::encoding::ForOverwrite<(), $ty>,
$($($where_clause)*)?
{
#[inline]
fn is_empty(val: &$ty) -> bool {
*val == <() as $crate::encoding::EmptyState<(), $ty>>::empty()
}
#[inline]
fn clear(val: &mut $ty) {
*val = <() as $crate::encoding::EmptyState<(), $ty>>::empty();
}
}
};
}
pub use empty_state_via_for_overwrite;
#[macro_export]
macro_rules! empty_state_via_default {
(
$ty:ty
$(, with generics ($($generics:tt)*))?
$(, with where clause ($($where_clause:tt)*))?
) => {
$crate::for_overwrite_via_default!(
$ty
$(, with generics ($($generics)*))?
$(, with where clause ($($where_clause)*))?
);
$crate::empty_state_via_for_overwrite!(
$ty
$(, with generics ($($generics)*))?
$(, with where clause ($($where_clause)*))?
);
};
}
pub use empty_state_via_default;
pub trait Enumeration: Eq + Sized {
fn to_number(&self) -> u32;
fn try_from_number(n: u32) -> Result<Self, u32>;
fn is_valid(n: u32) -> bool;
}
#[allow(clippy::len_without_is_empty)]
pub trait Collection
where
(): EmptyState<(), Self>,
{
type Item;
type RefIter<'a>: ExactSizeIterator<Item = &'a Self::Item>
where
Self::Item: 'a,
Self: 'a;
type ReverseIter<'a>: Iterator<Item = &'a Self::Item>
where
Self::Item: 'a,
Self: 'a;
fn len(&self) -> usize;
fn iter(&self) -> Self::RefIter<'_>;
fn reversed(&self) -> Self::ReverseIter<'_>;
fn insert(&mut self, item: Self::Item) -> Result<(), DecodeErrorKind>;
}
pub trait DistinguishedCollection: Collection + Eq
where
(): EmptyState<(), Self>,
{
fn insert_distinguished(&mut self, item: Self::Item) -> Result<Canonicity, DecodeErrorKind>;
}
pub(crate) trait TriviallyDistinguishedCollection {}
impl<T> DistinguishedCollection for T
where
T: Eq + Collection + TriviallyDistinguishedCollection,
(): EmptyState<(), T>,
{
#[inline]
fn insert_distinguished(&mut self, item: Self::Item) -> Result<Canonicity, DecodeErrorKind> {
self.insert(item).map(|()| Canonicity::Canonical)
}
}
#[allow(clippy::len_without_is_empty)]
pub trait Mapping
where
(): EmptyState<(), Self>,
{
type Key;
type Value;
type RefIter<'a>: ExactSizeIterator<Item = (&'a Self::Key, &'a Self::Value)>
where
Self::Key: 'a,
Self::Value: 'a,
Self: 'a;
type ReverseIter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)>
where
Self::Key: 'a,
Self::Value: 'a,
Self: 'a;
fn len(&self) -> usize;
fn iter(&self) -> Self::RefIter<'_>;
fn reversed(&self) -> Self::ReverseIter<'_>;
fn insert(&mut self, key: Self::Key, value: Self::Value) -> Result<(), DecodeErrorKind>;
}
pub trait DistinguishedMapping: Mapping
where
(): EmptyState<(), Self>,
{
fn insert_distinguished(
&mut self,
key: Self::Key,
value: Self::Value,
) -> Result<Canonicity, DecodeErrorKind>;
}