use crate::{Attribute, Node};
use alloc::vec::Vec;
use core::fmt::Debug;
pub use tree_path::TreePath;
mod tree_path;
#[derive(Clone, Debug, PartialEq)]
pub struct 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 tag: Option<&'a Tag>,
pub patch_path: TreePath,
pub patch_type: PatchType<'a, Ns, Tag, Leaf, Att, Val>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum PatchType<'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 {
nodes: Vec<&'a Node<Ns, Tag, Leaf, Att, Val>>,
},
InsertAfterNode {
nodes: Vec<&'a Node<Ns, Tag, Leaf, Att, Val>>,
},
AppendChildren {
children: Vec<&'a Node<Ns, Tag, Leaf, Att, Val>>,
},
RemoveNode,
MoveBeforeNode {
nodes_path: Vec<TreePath>,
},
MoveAfterNode {
nodes_path: Vec<TreePath>,
},
ReplaceNode {
replacement: Vec<&'a Node<Ns, Tag, Leaf, Att, Val>>,
},
AddAttributes {
attrs: Vec<&'a Attribute<Ns, Att, Val>>,
},
RemoveAttributes {
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 {
&self.patch_path
}
pub fn node_paths(&self) -> &[TreePath] {
match &self.patch_type {
PatchType::MoveBeforeNode { nodes_path } => nodes_path,
PatchType::MoveAfterNode { nodes_path } => nodes_path,
_ => &[],
}
}
pub fn tag(&self) -> Option<&Tag> {
self.tag
}
pub fn insert_before_node(
tag: Option<&'a Tag>,
patch_path: TreePath,
nodes: impl IntoIterator<Item = &'a Node<Ns, Tag, Leaf, Att, Val>>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::InsertBeforeNode {
nodes: nodes.into_iter().collect(),
},
}
}
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 {
tag,
patch_path,
patch_type: PatchType::InsertAfterNode { nodes },
}
}
pub fn append_children(
tag: Option<&'a Tag>,
patch_path: TreePath,
children: Vec<&'a Node<Ns, Tag, Leaf, Att, Val>>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::AppendChildren { children },
}
}
pub fn remove_node(
tag: Option<&'a Tag>,
patch_path: TreePath,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::RemoveNode,
}
}
pub fn move_before_node(
tag: Option<&'a Tag>,
patch_path: TreePath,
nodes_path: impl IntoIterator<Item = TreePath>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::MoveBeforeNode {
nodes_path: nodes_path.into_iter().collect(),
},
}
}
pub fn move_after_node(
tag: Option<&'a Tag>,
patch_path: TreePath,
nodes_path: impl IntoIterator<Item = TreePath>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::MoveAfterNode {
nodes_path: nodes_path.into_iter().collect(),
},
}
}
pub fn replace_node(
tag: Option<&'a Tag>,
patch_path: TreePath,
replacement: impl IntoIterator<Item = &'a Node<Ns, Tag, Leaf, Att, Val>>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag,
patch_path,
patch_type: PatchType::ReplaceNode {
replacement: replacement.into_iter().collect(),
},
}
}
pub fn add_attributes(
tag: &'a Tag,
patch_path: TreePath,
attrs: impl IntoIterator<Item = &'a Attribute<Ns, Att, Val>>,
) -> Patch<'a, Ns, Tag, Leaf, Att, Val> {
Patch {
tag: Some(tag),
patch_path,
patch_type: PatchType::AddAttributes {
attrs: attrs.into_iter().collect(),
},
}
}
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 {
tag: Some(tag),
patch_path,
patch_type: PatchType::RemoveAttributes { attrs },
}
}
}