use crate::diff::{apply, ApplyError, Change};
use crate::node::{Mark, Node};
use serde_json::Value;
pub struct Transform<'a> {
root: &'a mut Node,
changes: Vec<Change>,
}
impl Node {
pub fn transform(&mut self) -> Transform<'_> {
Transform {
root: self,
changes: Vec::new(),
}
}
}
impl<'a> Transform<'a> {
fn push(&mut self, change: Change) -> Result<&mut Self, ApplyError> {
apply(self.root, std::slice::from_ref(&change))?;
self.changes.push(change);
Ok(self)
}
pub fn set_attr(
&mut self,
path: Vec<usize>,
key: impl Into<String>,
value: impl Into<Value>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::SetAttr {
path,
key: key.into(),
value: value.into(),
})
}
pub fn remove_attr(
&mut self,
path: Vec<usize>,
key: impl Into<String>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::RemoveAttr {
path,
key: key.into(),
})
}
pub fn set_text(
&mut self,
path: Vec<usize>,
text: Option<String>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::SetText { path, text })
}
pub fn set_marks(
&mut self,
path: Vec<usize>,
marks: Option<Vec<Mark>>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::SetMarks { path, marks })
}
pub fn set_extra(
&mut self,
path: Vec<usize>,
key: impl Into<String>,
value: impl Into<Value>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::SetExtra {
path,
key: key.into(),
value: value.into(),
})
}
pub fn remove_extra(
&mut self,
path: Vec<usize>,
key: impl Into<String>,
) -> Result<&mut Self, ApplyError> {
self.push(Change::RemoveExtra {
path,
key: key.into(),
})
}
pub fn insert(
&mut self,
path: Vec<usize>,
index: usize,
node: Node,
) -> Result<&mut Self, ApplyError> {
self.push(Change::Insert { path, index, node })
}
pub fn remove(&mut self, path: Vec<usize>, index: usize) -> Result<&mut Self, ApplyError> {
self.push(Change::Remove { path, index })
}
pub fn replace(&mut self, path: Vec<usize>, node: Node) -> Result<&mut Self, ApplyError> {
self.push(Change::Replace { path, node })
}
pub fn move_child(
&mut self,
path: Vec<usize>,
from: usize,
to: usize,
) -> Result<&mut Self, ApplyError> {
self.push(Change::Move { path, from, to })
}
pub fn changes(&self) -> &[Change] {
&self.changes
}
pub fn finish(self) -> Vec<Change> {
self.changes
}
}