use std::collections::BTreeSet;
use crate::{EdgeID, NodeID};
pub type Nodes = BTreeSet<NodeID>;
pub type Edges = BTreeSet<EdgeID>;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ElementID {
Node(NodeID),
Edge(EdgeID),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Elements {
pub nodes: Nodes,
pub edges: Edges,
}
impl Elements {
pub fn new(nodes: Nodes, edges: Edges) -> Self {
Self { nodes, edges }
}
pub fn from_nodes(nodes: Nodes) -> Self {
Self::new(nodes, Edges::new())
}
pub fn from_edges(edges: Edges) -> Self {
Self::new(Nodes::new(), edges)
}
pub fn from_elements(elements: &[ElementID]) -> Self {
let nodes = elements
.iter()
.filter_map(|element| match element {
ElementID::Node(node) => Some(node),
_ => None,
})
.cloned()
.collect();
let edges = elements
.iter()
.filter_map(|element| match element {
ElementID::Edge(edge) => Some(edge),
_ => None,
})
.cloned()
.collect();
Self::new(nodes, edges)
}
}
impl Default for Elements {
fn default() -> Self {
Self::new(Nodes::new(), Edges::new())
}
}
impl From<Nodes> for Elements {
fn from(nodes: Nodes) -> Self {
Self::from_nodes(nodes)
}
}
impl From<Edges> for Elements {
fn from(edges: Edges) -> Self {
Self::from_edges(edges)
}
}
impl From<(Nodes, Edges)> for Elements {
fn from((nodes, edges): (Nodes, Edges)) -> Self {
Self::new(nodes, edges)
}
}
impl From<&Elements> for Elements {
fn from(elements: &Elements) -> Self {
elements.clone()
}
}
impl Elements {
pub fn contains(&self, member: &ElementID) -> bool {
match member {
ElementID::Node(node) => self.nodes.contains(node),
ElementID::Edge(edge) => self.edges.contains(edge),
}
}
pub fn insert(&mut self, new_member: ElementID) -> bool {
match new_member {
ElementID::Node(node) => self.nodes.insert(node),
ElementID::Edge(edge) => self.edges.insert(edge),
}
}
pub fn insert_all(&mut self, other: &Elements) {
self.nodes.extend(other.nodes.iter().cloned());
self.edges.extend(other.edges.iter().cloned());
}
pub fn remove(&mut self, member: &ElementID) -> bool {
match member {
ElementID::Node(node) => self.nodes.remove(node),
ElementID::Edge(edge) => self.edges.remove(edge),
}
}
pub fn remove_all(&mut self, other: &Elements) {
self.nodes = self.nodes.difference(&other.nodes).cloned().collect();
self.edges = self.edges.difference(&other.edges).cloned().collect();
}
pub fn union(&self, other: &Elements) -> Elements {
Elements::new(
self.nodes.union(&other.nodes).cloned().collect(),
self.edges.union(&other.edges).cloned().collect()
)
}
pub fn intersection(&self, other: &Elements) -> Elements {
Elements::new(
self.nodes.intersection(&other.nodes).cloned().collect(),
self.edges.intersection(&other.edges).cloned().collect()
)
}
pub fn difference(&self, other: &Elements) -> Elements {
Elements::new(
self.nodes.difference(&other.nodes).cloned().collect(),
self.edges.difference(&other.edges).cloned().collect()
)
}
pub fn symmetric_difference(&self, other: &Elements) -> Elements {
Elements::new(
self.nodes.symmetric_difference(&other.nodes).cloned().collect(),
self.edges.symmetric_difference(&other.edges).cloned().collect()
)
}
pub fn form_union(&mut self, other: &Elements) {
self.nodes = self.nodes.union(&other.nodes).cloned().collect();
self.edges = self.edges.union(&other.edges).cloned().collect();
}
pub fn form_intersection(&mut self, other: &Elements) {
self.nodes = self.nodes.intersection(&other.nodes).cloned().collect();
self.edges = self.edges.intersection(&other.edges).cloned().collect();
}
pub fn form_difference(&mut self, other: &Elements) {
self.nodes = self.nodes.difference(&other.nodes).cloned().collect();
self.edges = self.edges.difference(&other.edges).cloned().collect();
}
pub fn form_symmetric_difference(&mut self, other: &Elements) {
self.nodes = self.nodes.symmetric_difference
(&other.nodes).cloned().collect();
self.edges = self.edges.symmetric_difference
(&other.edges).cloned().collect();
}
pub fn is_disjoint(&self, other: &Elements) -> bool {
self.nodes.is_disjoint(&other.nodes) && self.edges.is_disjoint(&other.edges)
}
pub fn is_subset(&self, other: &Elements) -> bool {
self.nodes.is_subset(&other.nodes) && self.edges.is_subset(&other.edges)
}
pub fn is_superset(&self, other: &Elements) -> bool {
self.nodes.is_superset(&other.nodes) && self.edges.is_superset(&other.edges)
}
pub fn len(&self) -> usize {
self.nodes.len() + self.edges.len()
}
pub fn is_empty(&self) -> bool {
self.nodes.is_empty() && self.edges.is_empty()
}
pub fn clear(&mut self) {
self.nodes.clear();
self.edges.clear();
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&ElementID) -> bool,
{
self.nodes.retain(|node| f(&ElementID::Node(node.clone())));
self.edges.retain(|edge| f(&ElementID::Edge(edge.clone())));
}
}