1use crate::block::{BlockError, BlockRange};
38use crate::diff::{apply, ApplyError, Change};
39use crate::node::{Mark, Node};
40use crate::range::Position;
41use serde_json::{Map, Value};
42
43pub struct Transform<'a> {
50 root: &'a mut Node,
51 changes: Vec<Change>,
52}
53
54impl Node {
55 pub fn transform(&mut self) -> Transform<'_> {
57 Transform {
58 root: self,
59 changes: Vec::new(),
60 }
61 }
62}
63
64impl<'a> Transform<'a> {
65 fn push(&mut self, change: Change) -> Result<&mut Self, ApplyError> {
67 apply(self.root, std::slice::from_ref(&change))?;
68 self.changes.push(change);
69 Ok(self)
70 }
71
72 pub fn set_attr(
74 &mut self,
75 path: Vec<usize>,
76 key: impl Into<String>,
77 value: impl Into<Value>,
78 ) -> Result<&mut Self, ApplyError> {
79 self.push(Change::SetAttr {
80 path,
81 key: key.into(),
82 value: value.into(),
83 })
84 }
85
86 pub fn remove_attr(
88 &mut self,
89 path: Vec<usize>,
90 key: impl Into<String>,
91 ) -> Result<&mut Self, ApplyError> {
92 self.push(Change::RemoveAttr {
93 path,
94 key: key.into(),
95 })
96 }
97
98 pub fn set_text(
100 &mut self,
101 path: Vec<usize>,
102 text: Option<String>,
103 ) -> Result<&mut Self, ApplyError> {
104 self.push(Change::SetText { path, text })
105 }
106
107 pub fn set_marks(
109 &mut self,
110 path: Vec<usize>,
111 marks: Option<Vec<Mark>>,
112 ) -> Result<&mut Self, ApplyError> {
113 self.push(Change::SetMarks { path, marks })
114 }
115
116 pub fn set_extra(
118 &mut self,
119 path: Vec<usize>,
120 key: impl Into<String>,
121 value: impl Into<Value>,
122 ) -> Result<&mut Self, ApplyError> {
123 self.push(Change::SetExtra {
124 path,
125 key: key.into(),
126 value: value.into(),
127 })
128 }
129
130 pub fn remove_extra(
132 &mut self,
133 path: Vec<usize>,
134 key: impl Into<String>,
135 ) -> Result<&mut Self, ApplyError> {
136 self.push(Change::RemoveExtra {
137 path,
138 key: key.into(),
139 })
140 }
141
142 pub fn insert(
144 &mut self,
145 path: Vec<usize>,
146 index: usize,
147 node: Node,
148 ) -> Result<&mut Self, ApplyError> {
149 self.push(Change::Insert { path, index, node })
150 }
151
152 pub fn remove(&mut self, path: Vec<usize>, index: usize) -> Result<&mut Self, ApplyError> {
154 self.push(Change::Remove { path, index })
155 }
156
157 pub fn replace(&mut self, path: Vec<usize>, node: Node) -> Result<&mut Self, ApplyError> {
159 self.push(Change::Replace { path, node })
160 }
161
162 pub fn move_child(
165 &mut self,
166 path: Vec<usize>,
167 from: usize,
168 to: usize,
169 ) -> Result<&mut Self, ApplyError> {
170 self.push(Change::Move { path, from, to })
171 }
172
173 pub fn changes(&self) -> &[Change] {
175 &self.changes
176 }
177
178 pub fn finish(self) -> Vec<Change> {
180 self.changes
181 }
182}
183
184impl Transform<'_> {
190 fn record_structural<F>(&mut self, f: F) -> Result<&mut Self, BlockError>
191 where
192 F: FnOnce(&mut Node) -> Result<(), BlockError>,
193 {
194 let before = self.root.clone();
195 f(self.root)?;
196 let patch = before.diff(self.root);
197 self.changes.extend(patch);
198 Ok(self)
199 }
200
201 pub fn set_block_type(
203 &mut self,
204 path: Vec<usize>,
205 new_type: impl Into<String>,
206 attrs: Option<Map<String, Value>>,
207 ) -> Result<&mut Self, BlockError> {
208 self.record_structural(|root| root.set_block_type(&path, new_type, attrs))
209 }
210
211 pub fn split_block(
213 &mut self,
214 path: Vec<usize>,
215 at: usize,
216 depth: usize,
217 ) -> Result<&mut Self, BlockError> {
218 self.record_structural(|root| root.split_block(&path, at, depth))
219 }
220
221 pub fn split_block_at(
223 &mut self,
224 path: Vec<usize>,
225 pos: Position,
226 depth: usize,
227 ) -> Result<&mut Self, BlockError> {
228 self.record_structural(|root| root.split_block_at(&path, pos, depth))
229 }
230
231 pub fn join_blocks(
233 &mut self,
234 parent: Vec<usize>,
235 index: usize,
236 ) -> Result<&mut Self, BlockError> {
237 self.record_structural(|root| root.join_blocks(&parent, index))
238 }
239
240 pub fn wrap(
242 &mut self,
243 path: Vec<usize>,
244 wrapper_type: impl Into<String>,
245 attrs: Option<Map<String, Value>>,
246 ) -> Result<&mut Self, BlockError> {
247 self.record_structural(|root| root.wrap(&path, wrapper_type, attrs))
248 }
249
250 pub fn wrap_range(
252 &mut self,
253 range: BlockRange,
254 wrapper_type: impl Into<String>,
255 attrs: Option<Map<String, Value>>,
256 ) -> Result<&mut Self, BlockError> {
257 self.record_structural(|root| root.wrap_range(&range, wrapper_type, attrs))
258 }
259
260 pub fn lift(&mut self, path: Vec<usize>) -> Result<&mut Self, BlockError> {
262 self.record_structural(|root| root.lift(&path))
263 }
264}