1use crate::fragment::Fragment;
9use crate::map::Mapping;
10use crate::mark::Mark;
11use crate::node::Node;
12use crate::pos::ResolvedPos;
13use crate::schema::Schema;
14use crate::slice::Slice;
15use crate::step::{AddMarkStep, AttrStep, RemoveMarkStep, ReplaceStep, Step, StepError};
16
17#[derive(Debug, Clone)]
19pub struct Transform {
20 doc: Node,
21 steps: Vec<Box<dyn Step>>,
22 docs: Vec<Node>,
23 mapping: Mapping,
24}
25
26impl Transform {
27 pub fn new(doc: Node) -> Self {
29 Transform {
30 doc,
31 steps: Vec::new(),
32 docs: Vec::new(),
33 mapping: Mapping::new(),
34 }
35 }
36
37 pub fn doc(&self) -> &Node {
39 &self.doc
40 }
41
42 pub fn steps(&self) -> &[Box<dyn Step>] {
44 &self.steps
45 }
46
47 pub fn doc_before(&self, i: usize) -> &Node {
49 &self.docs[i]
50 }
51
52 pub fn mapping(&self) -> &Mapping {
54 &self.mapping
55 }
56
57 pub fn doc_changed(&self) -> bool {
59 !self.steps.is_empty()
60 }
61
62 pub fn step(&mut self, step: Box<dyn Step>, schema: &Schema) -> Result<&mut Self, StepError> {
64 let next = step.apply(&self.doc, schema)?;
65 self.mapping.append_map(step.get_map());
66 self.docs.push(std::mem::replace(&mut self.doc, next));
67 self.steps.push(step);
68 Ok(self)
69 }
70
71 pub fn replace(
73 &mut self,
74 from: usize,
75 to: usize,
76 slice: Slice,
77 schema: &Schema,
78 ) -> Result<&mut Self, StepError> {
79 self.step(Box::new(ReplaceStep::new(from, to, slice)), schema)
80 }
81
82 pub fn delete(
84 &mut self,
85 from: usize,
86 to: usize,
87 schema: &Schema,
88 ) -> Result<&mut Self, StepError> {
89 self.replace(from, to, Slice::empty(), schema)
90 }
91
92 pub fn insert(
94 &mut self,
95 pos: usize,
96 slice: Slice,
97 schema: &Schema,
98 ) -> Result<&mut Self, StepError> {
99 self.replace(pos, pos, slice, schema)
100 }
101
102 pub fn add_mark(
104 &mut self,
105 from: usize,
106 to: usize,
107 mark: Mark,
108 schema: &Schema,
109 ) -> Result<&mut Self, StepError> {
110 self.step(Box::new(AddMarkStep::new(from, to, mark)), schema)
111 }
112
113 pub fn remove_mark(
115 &mut self,
116 from: usize,
117 to: usize,
118 mark: Mark,
119 schema: &Schema,
120 ) -> Result<&mut Self, StepError> {
121 self.step(Box::new(RemoveMarkStep::new(from, to, mark)), schema)
122 }
123
124 pub fn split(&mut self, pos: usize, schema: &Schema) -> Result<&mut Self, StepError> {
127 self.split_at_depth(pos, 1, schema)
128 }
129
130 pub fn split_at_depth(
136 &mut self,
137 pos: usize,
138 levels: usize,
139 schema: &Schema,
140 ) -> Result<&mut Self, StepError> {
141 if levels == 0 {
142 return Err(StepError("split_at_depth requires levels >= 1".into()));
143 }
144 let rp = ResolvedPos::resolve(self.doc(), pos).map_err(|e| StepError(e.to_string()))?;
145 if rp.depth() < levels {
146 return Err(StepError(format!(
147 "split_at_depth({levels}) needs at least {levels} ancestors at pos {pos}, found {}",
148 rp.depth()
149 )));
150 }
151 let deepest = rp.parent().clone();
153 let mut inner = deepest.copy_content(Fragment::empty());
154 for d in (rp.depth() - levels + 1..rp.depth()).rev() {
155 let outer = rp.node(d).clone();
156 inner = outer.copy_content(Fragment::from_node(inner));
157 }
158 let content = Fragment::from_node(inner.clone()).append(&Fragment::from_node(inner));
159 self.replace(pos, pos, Slice::new(content, levels, levels), schema)
160 }
161
162 pub fn set_node_attr(
164 &mut self,
165 pos: usize,
166 attr: &str,
167 value: serde_json::Value,
168 schema: &Schema,
169 ) -> Result<&mut Self, StepError> {
170 self.step(Box::new(AttrStep::new(pos, attr, value)), schema)
171 }
172
173 pub fn invert_steps(&self) -> Result<Vec<Box<dyn Step>>, StepError> {
176 let mut inverted = Vec::with_capacity(self.steps.len());
177 for i in (0..self.steps.len()).rev() {
178 inverted.push(self.steps[i].invert(&self.docs[i])?);
179 }
180 Ok(inverted)
181 }
182}