use rpds::VectorSync;
use super::attrs::Attrs;
use super::mark::Mark;
use super::types::NodeId;
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Node {
#[serde(rename = "i")]
pub id: NodeId,
#[serde(rename = "t")]
pub r#type: String,
#[serde(rename = "a")]
pub attrs: Attrs,
#[serde(rename = "c")]
pub content: VectorSync<NodeId>, #[serde(rename = "m")]
pub marks: VectorSync<Mark>,
}
impl Node {
pub fn new(
id: &str, r#type: String,
attrs: Attrs,
content: Vec<NodeId>,
marks: Vec<Mark>,
) -> Self {
let mut vector = rpds::VectorSync::new_sync();
for c in content {
vector = vector.push_back(c);
}
let mut mks = rpds::VectorSync::new_sync();
for m in marks {
mks = mks.push_back(m);
}
Node {
id: id.into(), r#type,
attrs,
content: vector,
marks: mks,
}
}
pub fn child_count(&self) -> usize {
self.content.len()
}
pub fn update_attr(
&self,
new_values: rpds::HashTrieMapSync<String, Value>,
) -> Self {
let mut new_node = self.clone();
let new_attrs = self.attrs.update(new_values);
new_node.attrs = new_attrs;
new_node
}
pub fn insert_content_at_index(
&self,
index: usize,
node_id: &str,
) -> Self {
let mut new_node = self.clone(); new_node.content = self
.content
.iter()
.take(index)
.cloned()
.chain(std::iter::once(node_id.into()))
.chain(self.content.iter().skip(index).cloned())
.collect();
new_node
}
pub fn insert_contents(
&self,
node_ids: &Vec<NodeId>,
) -> Self {
let mut new_node = self.clone();
for node_id in node_ids {
new_node.content = new_node.content.push_back(node_id.clone());
}
new_node
}
pub fn contains(
&self,
id: &NodeId,
) -> bool {
self.content.iter().any(|x| x.eq(id))
}
pub fn remove_content(
&mut self,
id: &NodeId,
) -> Self {
let mut new_node = self.clone();
let mut new_vector = VectorSync::new_sync();
for c in self.content.iter() {
if !c.eq(id) {
new_vector.push_back_mut(c.clone());
}
}
new_node.content = new_vector;
new_node
}
pub fn swap(
&self,
i: usize,
j: usize,
) -> Option<Node> {
if i >= self.content.len() || j >= self.content.len() {
return None;
}
let value_i = self.content.get(i)?;
let value_j = self.content.get(j)?;
let mut new_vector = self.content.clone();
new_vector.set_mut(i, value_j.clone());
new_vector.set_mut(j, value_i.clone());
let mut new_node = self.clone();
new_node.content = new_vector;
Some(new_node)
}
pub fn insert_content(
&self,
node_id: &str,
) -> Self {
let mut new_node = self.clone();
new_node.content = new_node.content.push_back(node_id.into());
new_node
}
pub fn remove_mark_by_name(
&self,
mark_name: &str,
) -> Self {
let mut new_node = self.clone();
new_node.marks = new_node
.marks
.iter()
.filter(|&m| m.r#type != mark_name)
.cloned()
.collect();
new_node
}
pub fn remove_mark(
&self,
mark_types: &[String],
) -> Self {
let mut new_node = self.clone();
new_node.marks = new_node
.marks
.iter()
.filter(|&m| !mark_types.contains(&m.r#type))
.cloned()
.collect();
new_node
}
pub fn add_marks(
&self,
marks: &[Mark],
) -> Self {
let mark_types =
marks.iter().map(|m| m.r#type.clone()).collect::<Vec<String>>();
let mut new_node = self.clone();
new_node.marks = new_node
.marks
.iter()
.filter(|m| !mark_types.contains(&m.r#type))
.cloned()
.collect();
new_node.marks.extend(marks.iter().cloned());
new_node
}
}