use crate::operations::*;
#[cfg(feature = "derive")]
pub use finit_derive::{SetEq, SubsetOf};
pub trait SetEq<Rhs = Self> {
fn set_eq(&self, rhs: &Rhs) -> bool;
}
impl<T: SetEq<Rhs>, Rhs> SetEq<Rhs> for &T {
fn set_eq(&self, rhs: &Rhs) -> bool {
T::set_eq(*self, rhs)
}
}
#[macro_export]
macro_rules! set_eq_partial_eq_impl {
(($($wh:tt)+): $($t:tt)+) => {
impl<$($wh)*> $crate::comparisons::SetEq for $($t)* {
fn set_eq(&self, rhs: &Self) -> bool {
PartialEq::eq(self, rhs)
}
}
};
($t:ty) => {
impl $crate::comparisons::SetEq for $t {
fn set_eq(&self, rhs: &Self) -> bool {
PartialEq::eq(self, rhs)
}
}
};
($($t:ty),*) => {
$(
set_eq_partial_eq_impl!($t);
)*
};
}
pub trait SubsetOf<Rhs = Self> {
fn subset_of(&self, rhs: &Rhs) -> bool;
}
impl<T: SubsetOf<Rhs>, Rhs> SubsetOf<Rhs> for &T {
fn subset_of(&self, rhs: &Rhs) -> bool {
T::subset_of(*self, rhs)
}
}
#[macro_export]
macro_rules! subset_of_intersection_identity_impl {
($t:ty) => {
impl $crate::comparisons::SubsetOf for $t {
fn subset_of(&self, rhs: &Self) -> bool {
$crate::comparisons::identity::subset_using_intersection_eq(self, rhs)
}
}
};
($($t:ty),*) => {
$(
subset_of_intersection_identity_impl!($t);
)*
};
}
pub trait StrictSubsetOf<Rhs = Self> {
fn strict_subset_of(&self, rhs: &Rhs) -> bool;
}
impl<T: SubsetOf<Rhs> + SetEq<Rhs>, Rhs> StrictSubsetOf<Rhs> for T {
fn strict_subset_of(&self, rhs: &Rhs) -> bool {
self.subset_of(rhs) && !self.set_eq(rhs)
}
}
pub trait SupersetOf<Rhs = Self> {
fn superset_of(&self, rhs: &Rhs) -> bool;
}
impl<T, Rhs: SubsetOf<T>> SupersetOf<Rhs> for T {
fn superset_of(&self, rhs: &Rhs) -> bool {
rhs.subset_of(self)
}
}
pub trait StrictSupersetOf<Rhs = Self> {
fn strict_superset_of(&self, rhs: &Rhs) -> bool;
}
impl<T, Rhs: StrictSubsetOf<T>> StrictSupersetOf<Rhs> for T {
fn strict_superset_of(&self, rhs: &Rhs) -> bool {
rhs.strict_subset_of(self)
}
}
pub mod identity {
use crate::Set;
use super::*;
pub fn subset_using_intersection_eq<T, Rhs>(a: &T, b: &Rhs) -> bool
where
T: Clone + SetEq,
for<'a> T: IntersectionAssign<&'a Rhs>,
{
let mut intersection = a.clone();
intersection.intersection_assign(b);
intersection.set_eq(a)
}
pub fn subset_using_union_eq<T, Rhs>(a: &T, b: &Rhs) -> bool
where
Rhs: Clone + SetEq,
for<'a> Rhs: UnionAssign<&'a T>,
{
let mut union_set = b.clone();
union_set.union_assign(a);
union_set.set_eq(b)
}
pub fn subset_using_difference_empty<T, Rhs>(a: &T, b: &Rhs) -> bool
where
T: Clone + Set,
for<'a> T: DifferenceAssign<&'a Rhs>,
{
let mut difference = a.clone();
difference.difference_assign(b);
difference.is_empty()
}
pub fn eq_using_subset<T, Rhs>(a: &T, b: &Rhs) -> bool
where
T: SubsetOf<Rhs>,
Rhs: SubsetOf<T>,
{
a.subset_of(b) && b.subset_of(a)
}
}