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 + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
InsertBeforeNode {
tag: Option<&'a TAG>,
patch_path: TreePath,
nodes: Vec<&'a Node<NS, TAG, LEAF, ATT, VAL>>,
},
InsertAfterNode {
tag: Option<&'a TAG>,
patch_path: TreePath,
nodes: Vec<&'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>>,
},
}
impl<'a, NS, TAG, LEAF, ATT, VAL> Patch<'a, NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
pub fn path(&self) -> &TreePath {
match self {
Patch::InsertBeforeNode { patch_path, .. } => &patch_path,
Patch::InsertAfterNode { patch_path, .. } => &patch_path,
Patch::AppendChildren { patch_path, .. } => &patch_path,
Patch::RemoveNode { patch_path, .. } => &patch_path,
Patch::ReplaceNode { patch_path, .. } => &patch_path,
Patch::AddAttributes { patch_path, .. } => &patch_path,
Patch::RemoveAttributes { patch_path, .. } => &patch_path,
}
}
pub fn tag(&self) -> Option<&TAG> {
match self {
Patch::InsertBeforeNode { tag, .. } => *tag,
Patch::InsertAfterNode { 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),
}
}
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::InsertBeforeNode {
tag,
patch_path,
nodes: vec![node],
}
}
pub fn insert_before_node(
tag: Option<&'a TAG>,
patch_path: TreePath,
nodes: Vec<&'a Node<NS, TAG, LEAF, ATT, VAL>>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::InsertBeforeNode {
tag,
patch_path,
nodes,
}
}
pub fn insert_after_node(
tag: Option<&'a TAG>,
patch_path: TreePath,
nodes: Vec<&'a Node<NS, TAG, LEAF, ATT, VAL>>,
) -> Patch<'a, NS, TAG, LEAF, ATT, VAL> {
Patch::InsertAfterNode {
tag,
patch_path,
nodes,
}
}
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,
}
}
}