use super::TreeView;
use crate::slab::Key;
use crate::tree::AsNodePath;
use crate::tree::nodepath::new_node_path;
pub struct InsertTransaction<'a, 'tree, T> {
tree: &'a mut TreeView<'tree, T>,
node_id: Key,
source: &'a [u16],
}
impl<'a, 'tree, T> InsertTransaction<'a, 'tree, T> {
pub fn new(tree: &'a mut TreeView<'tree, T>, source: &'a [u16]) -> Self {
let node_id = tree.values.next_id();
Self { tree, node_id, source }
}
pub fn node_id(&self) -> Key {
self.node_id
}
pub fn commit_child(self, value: T) -> Option<Key> {
assert_eq!(self.tree.offset, &self.source[..self.tree.offset.len()]);
let relative = &self.source[self.tree.offset.len()..];
let node_id = self.tree.layout.with_mut(relative, |nodes| {
let node_path = new_node_path(self.source, nodes.len() as u16);
let node_id = self.tree.values.insert((node_path, value));
nodes.push(node_id);
node_id
})?;
debug_assert_eq!(node_id, self.node_id);
Some(self.node_id)
}
pub fn commit_at(self, value: T) -> Option<Key> {
let (parent, index) = self.source.split_parent()?;
let node_id = self.tree.layout.with_mut(parent, |siblings| {
let path = crate::tree::nodepath::join(self.tree.offset, self.source);
let value_id = self.tree.values.insert((path, value));
siblings.insert(index, value_id);
siblings.inner[index + 1..].iter_mut().for_each(|node| {
let (path, _) = self.tree.values.get_mut(node.value).expect("every node has a value");
path[path.len() - 1] += 1;
let path = path.clone();
node.reparent(&path, self.tree.values);
});
value_id
})?;
debug_assert_eq!(node_id, self.node_id);
Some(node_id)
}
}