use std::ops::BitOr;
use crate::{
error::PoolResult, id_generator::IdGenerator, mark::Mark, node::Node,
types::NodeId,
};
use super::{MarkRef, NodeRef};
impl<'a> BitOr<NodeId> for NodeRef<'a> {
type Output = PoolResult<NodeRef<'a>>;
fn bitor(
self,
other_node_id: NodeId,
) -> Self::Output {
let other_children =
self.tree.children(&other_node_id).unwrap_or_default();
let mut nodes_to_add = Vec::new();
for child_id in other_children.iter() {
if let Some(child_node) = self.tree.get_node(&child_id) {
let mut node = child_node.clone();
node.id = IdGenerator::get_id();
nodes_to_add.push(node);
}
}
if !nodes_to_add.is_empty() {
self.tree.add_node(&self.key.clone(), &nodes_to_add)?;
}
Ok(NodeRef::new(self.tree, self.key.clone()))
}
}
impl<'a> BitOr<Vec<NodeId>> for NodeRef<'a> {
type Output = PoolResult<NodeRef<'a>>;
fn bitor(
self,
other_node_ids: Vec<NodeId>,
) -> Self::Output {
let mut all_nodes_to_add = Vec::new();
for node_id in other_node_ids {
let children = self.tree.children(&node_id).unwrap_or_default();
for child_id in children.iter() {
if let Some(child_node) = self.tree.get_node(&child_id) {
let mut node = child_node.clone();
node.id = IdGenerator::get_id();
all_nodes_to_add.push(node);
}
}
}
if !all_nodes_to_add.is_empty() {
self.tree.add_node(&self.key.clone(), &all_nodes_to_add)?;
}
Ok(NodeRef::new(self.tree, self.key.clone()))
}
}
impl<'a> BitOr<Vec<Node>> for NodeRef<'a> {
type Output = PoolResult<NodeRef<'a>>;
fn bitor(
self,
nodes: Vec<Node>,
) -> Self::Output {
if !nodes.is_empty() {
self.tree.add_node(&self.key.clone(), &nodes)?;
}
Ok(NodeRef::new(self.tree, self.key.clone()))
}
}
impl<'a> BitOr<Mark> for MarkRef<'a> {
type Output = PoolResult<MarkRef<'a>>;
fn bitor(
self,
mark: Mark,
) -> Self::Output {
let existing_marks =
self.tree.get_marks(&self.key.clone()).unwrap_or_default();
let mark_exists = existing_marks.iter().any(|existing_mark| {
existing_mark.r#type == mark.r#type
&& existing_mark.attrs == mark.attrs
});
if !mark_exists {
self.tree.add_mark(&self.key.clone(), &[mark])?;
}
Ok(MarkRef::new(self.tree, self.key.clone()))
}
}
impl<'a> BitOr<Vec<Mark>> for MarkRef<'a> {
type Output = PoolResult<MarkRef<'a>>;
fn bitor(
self,
marks: Vec<Mark>,
) -> Self::Output {
let existing_marks =
self.tree.get_marks(&self.key.clone()).unwrap_or_default();
let mut unique_marks = Vec::new();
for mark in marks {
let mark_exists = existing_marks.iter().any(|existing_mark| {
existing_mark.r#type == mark.r#type
&& existing_mark.attrs == mark.attrs
});
if !mark_exists {
unique_marks.push(mark);
}
}
if !unique_marks.is_empty() {
self.tree.add_mark(&self.key.clone(), &unique_marks)?;
}
Ok(MarkRef::new(self.tree, self.key.clone()))
}
}