use alloc::collections::{btree_set::Iter, BTreeSet};
use owner_monad::{Owner, OwnerMut};
#[derive(Debug, PartialEq, Eq)]
pub struct Set<T>(BTreeSet<T>);
impl<T: Ord> Set<T> {
pub fn new() -> Self {
Self::default()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> Iter<T> {
self.0.iter()
}
}
impl<T: Ord> Default for Set<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T: Ord> IntoIterator for Set<T> {
type Item = T;
type IntoIter = <BTreeSet<T> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T: Ord> IntoIterator for &'a Set<T> {
type Item = &'a T;
type IntoIter = <&'a BTreeSet<T> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
#[allow(clippy::into_iter_on_ref)]
(&self.0).into_iter()
}
}
pub struct SetHandle<T: Ord, O: OwnerMut<Set<T>>> {
item: T,
owner: O,
}
impl<T: Ord, O: OwnerMut<Set<T>>> Drop for SetHandle<T, O> {
fn drop(&mut self) {
let item = &self.item;
self.owner.with(|set| set.0.remove(item));
}
}
impl<T: Ord, O: OwnerMut<Set<T>>> Owner<O> for SetHandle<T, O> {
fn with<'a, U>(&'a self, f: impl FnOnce(&O) -> U) -> Option<U>
where
O: 'a,
{
Some(f(&self.owner))
}
}
pub fn insert<T: Clone + Ord, O: OwnerMut<Set<T>>>(
mut owner: O,
item: T,
) -> Option<SetHandle<T, O>> {
if owner.with(|set| set.0.insert(item.clone()))? {
Some(SetHandle { item, owner })
} else {
None
}
}