2022-08-16 16:25:52 +08:00
|
|
|
use crate::core::document::position::Position;
|
2022-08-17 16:48:45 +08:00
|
|
|
use crate::core::{NodeData, Transaction};
|
2022-08-16 16:25:52 +08:00
|
|
|
use indextree::{Arena, NodeId};
|
|
|
|
|
|
|
|
pub struct DocumentTree {
|
|
|
|
arena: Arena<NodeData>,
|
|
|
|
root: NodeId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DocumentTree {
|
|
|
|
pub fn new() -> DocumentTree {
|
|
|
|
let mut arena = Arena::new();
|
|
|
|
let root = arena.new_node(NodeData::new("root".into()));
|
|
|
|
DocumentTree {
|
|
|
|
arena: Arena::new(),
|
|
|
|
root,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn node_at_path(&self, position: &Position) -> Option<NodeId> {
|
|
|
|
if position.is_empty() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut iterate_node = self.root;
|
|
|
|
|
|
|
|
for id in &position.0 {
|
|
|
|
let child = self.child_at_index_of_path(iterate_node, id.clone());
|
|
|
|
iterate_node = match child {
|
|
|
|
Some(node) => node,
|
|
|
|
None => return None,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(iterate_node)
|
|
|
|
}
|
|
|
|
|
2022-08-17 16:48:45 +08:00
|
|
|
pub fn path_of_node(&self, node_id: NodeId) -> Position {
|
|
|
|
let mut path: Vec<usize> = Vec::new();
|
|
|
|
|
|
|
|
let mut ancestors = node_id.ancestors(&self.arena);
|
|
|
|
let mut current_node = node_id;
|
|
|
|
let mut parent = ancestors.next();
|
|
|
|
|
|
|
|
while parent.is_some() {
|
|
|
|
let parent_node = parent.unwrap();
|
|
|
|
let counter = self.index_of_node(parent_node, current_node);
|
|
|
|
path.push(counter);
|
|
|
|
current_node = parent_node;
|
|
|
|
parent = ancestors.next();
|
|
|
|
}
|
|
|
|
|
|
|
|
Position(path)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn index_of_node(&self, parent_node: NodeId, child_node: NodeId) -> usize {
|
|
|
|
let mut counter: usize = 0;
|
|
|
|
|
|
|
|
let mut children_iterator = parent_node.children(&self.arena);
|
|
|
|
let mut node = children_iterator.next();
|
|
|
|
|
|
|
|
while node.is_some() {
|
|
|
|
if node.unwrap() == child_node {
|
|
|
|
return counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
node = children_iterator.next();
|
|
|
|
counter += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
counter
|
|
|
|
}
|
|
|
|
|
2022-08-16 16:25:52 +08:00
|
|
|
fn child_at_index_of_path(&self, at_node: NodeId, index: usize) -> Option<NodeId> {
|
|
|
|
let children = at_node.children(&self.arena);
|
|
|
|
|
|
|
|
let mut counter = 0;
|
|
|
|
for child in children {
|
|
|
|
if counter == index {
|
|
|
|
return Some(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
counter += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
2022-08-17 16:48:45 +08:00
|
|
|
|
|
|
|
pub fn apply(&self, _transaction: Transaction) {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
2022-08-16 16:25:52 +08:00
|
|
|
}
|