use std::boxed::Box;
use std::mem;
use super::{Prefix, Range};
use crate::traits::{self, Afi};
mod iter;
use self::iter::{Prefixes, Ranges};
mod node;
use self::node::Node;
mod ops;
#[derive(Clone, Debug)]
pub struct Set<A: Afi> {
root: Option<Box<Node<A>>>,
}
impl<A: Afi> Set<A> {
#[must_use]
pub const fn new() -> Self {
Self::new_with_root(None)
}
const fn new_with_root(root: Option<Box<Node<A>>>) -> Self {
Self { root }
}
fn insert_node(&mut self, new: Box<Node<A>>) -> &mut Self {
match mem::take(&mut self.root) {
Some(root) => {
self.root = Some(root.add(new));
}
None => {
self.root = Some(new);
}
};
self
}
pub(crate) fn insert_only<T>(&mut self, item: T) -> &mut Self
where
T: Into<Node<A>>,
{
self.insert_node(item.into().boxed())
}
pub fn insert<T>(&mut self, item: T) -> &mut Self
where
T: Into<Node<A>>,
{
self.insert_only(item).aggregate()
}
pub fn insert_from<I, T>(&mut self, iter: I) -> &mut Self
where
I: IntoIterator<Item = T>,
T: Into<Node<A>>,
{
iter.into_iter()
.fold(self, |set, item| set.insert_only(item))
.aggregate()
}
fn remove_node(&mut self, mut old: Box<Node<A>>) -> &mut Self {
if let Some(root) = mem::take(&mut self.root) {
self.root = Some(root.remove(&mut old));
};
self
}
pub fn remove<T>(&mut self, item: T) -> &mut Self
where
T: Into<Node<A>>,
{
self.remove_node(item.into().boxed()).aggregate()
}
pub fn remove_from<I, T>(&mut self, iter: I) -> &mut Self
where
I: IntoIterator<Item = T>,
T: Into<Node<A>>,
{
iter.into_iter()
.fold(self, |set, item| set.remove_node(item.into().boxed()))
.aggregate()
}
pub(crate) fn aggregate(&mut self) -> &mut Self {
if let Some(root) = mem::take(&mut self.root) {
self.root = root.aggregate(None);
}
self
}
pub fn clear(&mut self) {
self.root = None;
}
}
impl<'a, A: Afi> traits::PrefixSet<'a> for Set<A> {
type Prefix = Prefix<A>;
type Range = Range<A>;
type Prefixes = Prefixes<'a, A>;
type Ranges = Ranges<'a, A>;
fn prefixes(&'a self) -> Self::Prefixes {
self.into()
}
fn ranges(&'a self) -> Self::Ranges {
self.into()
}
fn contains(&self, prefix: Self::Prefix) -> bool {
self.root
.as_ref()
.map_or(false, |root| root.search(&prefix.into()).is_some())
}
}
impl<A: Afi> Default for Set<A> {
fn default() -> Self {
Self::new()
}
}
impl<A: Afi, U> Extend<U> for Set<A>
where
U: Into<Node<A>>,
{
#[allow(unused_results)]
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = U>,
{
self.insert_from(iter);
}
}
impl<A: Afi, T> FromIterator<T> for Set<A>
where
T: Into<Node<A>>,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
Self::new().insert_from(iter).clone()
}
}
#[cfg(test)]
mod tests;