use crate::{Attribute, Node};
use std::fmt::Debug;
pub use tree_path::TreePath;
mod tree_path;
#[derive(Clone, Debug, PartialEq)]
pub enum Patch<'a, NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
InsertNode {
tag: Option<&'a TAG>,
patch_path: TreePath,
node: &'a Node<NS, TAG, LEAF, ATT, VAL>,
},
AppendChildren {
tag: &'a TAG,
patch_path: TreePath,
children: Vec<&'a Node<NS, TAG, LEAF, ATT, VAL>>,
},
RemoveNode {
tag: Option<&'a TAG>,
patch_path: TreePath,
},
ReplaceNode {
tag: Option<&'a TAG>,
patch_path: TreePath,
replacement: &'a Node<NS, TAG, LEAF, ATT, VAL>,
},
AddAttributes {
tag: &'a TAG,
patch_path: TreePath,
attrs: Vec<&'a Attribute<NS, ATT, VAL>>,
},
RemoveAttributes {
tag: &'a TAG,
patch_path: TreePath,
attrs: Vec<&'a Attribute<NS, ATT, VAL>>,
},
ReplaceLeaf {
patch_path: TreePath,
old: &'a LEAF,
new: &'a LEAF,
},
}
impl<'a, NS, TAG, LEAF, ATT, VAL> Patch<'a, NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
pub fn path(&self) -> &[usize] {
match self {
Patch::InsertNode { patch_path, .. } => &patch_path.path,
Patch::AppendChildren { patch_path, .. } => &patch_path.path,
Patch::RemoveNode { patch_path, .. } => &patch_path.path,
Patch::ReplaceNode { patch_path, .. } => &patch_path.path,
Patch::AddAttributes { patch_path, .. } => &patch_path.path,
Patch::RemoveAttributes { patch_path, .. } => &patch_path.path,
Patch::ReplaceLeaf { patch_path, .. } => &patch_path.path,
}
}
pub fn tag(&self) -> Option<&TAG> {
match self {
Patch::InsertNode { tag, .. } => *tag,
Patch::AppendChildren { tag, .. } => Some(tag),
Patch::RemoveNode { tag, .. } => *tag,
Patch::ReplaceNode { tag, .. } => *tag,
Patch::AddAttributes { tag, .. } => Some(tag),
Patch::RemoveAttributes { tag, .. } => Some(tag),
Patch::ReplaceLeaf { .. } => None,
}
}
pub fn insert_node(
tag: Option<&'a TAG>,
patch_path: TreePath,
node: &'a Node<NS, TAG, LEAF, ATT, VAL>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::InsertNode {
tag,
patch_path,
node,
}
}
pub fn append_children(
tag: &'a TAG,
patch_path: TreePath,
children: Vec<&'a Node<NS, TAG, LEAF, ATT, VAL>>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::AppendChildren {
tag,
patch_path,
children,
}
}
pub fn remove_node(
tag: Option<&'a TAG>,
patch_path: TreePath,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::RemoveNode { tag, patch_path }
}
pub fn replace_node(
tag: Option<&'a TAG>,
patch_path: TreePath,
replacement: &'a Node<NS, TAG, LEAF, ATT, VAL>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::ReplaceNode {
tag,
patch_path,
replacement,
}
}
pub fn add_attributes(
tag: &'a TAG,
patch_path: TreePath,
attrs: Vec<&'a Attribute<NS, ATT, VAL>>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::AddAttributes {
tag,
patch_path,
attrs,
}
}
pub fn remove_attributes(
tag: &'a TAG,
patch_path: TreePath,
attrs: Vec<&'a Attribute<NS, ATT, VAL>>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::RemoveAttributes {
tag,
patch_path,
attrs,
}
}
pub fn replace_leaf(
patch_path: TreePath,
old: &'a LEAF,
new: &'a LEAF,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::ReplaceLeaf {
patch_path,
old,
new,
}
}
}