tiptap_rusty_parser/
mutate.rs1use crate::node::{Mark, Node};
4use serde_json::{Map, Value};
5
6impl Node {
7 pub fn has_mark(&self, mark_type: &str) -> bool {
11 self.marks
12 .as_ref()
13 .is_some_and(|m| m.iter().any(|x| x.mark_type == mark_type))
14 }
15
16 pub fn get_mark(&self, mark_type: &str) -> Option<&Mark> {
18 self.marks
19 .as_ref()?
20 .iter()
21 .find(|x| x.mark_type == mark_type)
22 }
23
24 pub fn add_mark(&mut self, mark: Mark) -> bool {
26 if self.has_mark(&mark.mark_type) {
27 return false;
28 }
29 self.marks.get_or_insert_with(Vec::new).push(mark);
30 true
31 }
32
33 pub fn remove_mark(&mut self, mark_type: &str) -> usize {
35 let Some(marks) = self.marks.as_mut() else {
36 return 0;
37 };
38 let before = marks.len();
39 marks.retain(|m| m.mark_type != mark_type);
40 let removed = before - marks.len();
41 if marks.is_empty() {
42 self.marks = None;
43 }
44 removed
45 }
46
47 pub fn toggle_mark(&mut self, mark: Mark) -> bool {
49 if self.has_mark(&mark.mark_type) {
50 self.remove_mark(&mark.mark_type);
51 false
52 } else {
53 self.add_mark(mark);
54 true
55 }
56 }
57
58 pub fn set_mark_attr(
60 &mut self,
61 mark_type: &str,
62 key: impl Into<String>,
63 value: impl Into<Value>,
64 ) -> bool {
65 let Some(marks) = self.marks.as_mut() else {
66 return false;
67 };
68 let Some(mark) = marks.iter_mut().find(|m| m.mark_type == mark_type) else {
69 return false;
70 };
71 mark.attrs
72 .get_or_insert_with(Map::new)
73 .insert(key.into(), value.into());
74 true
75 }
76
77 pub fn clear_marks(&mut self) {
79 self.marks = None;
80 }
81
82 pub fn attr(&self, key: &str) -> Option<&Value> {
86 self.attrs.as_ref()?.get(key)
87 }
88
89 pub fn attrs_mut(&mut self) -> &mut Map<String, Value> {
91 self.attrs.get_or_insert_with(Map::new)
92 }
93
94 pub fn set_attr(&mut self, key: impl Into<String>, value: impl Into<Value>) -> Option<Value> {
96 self.attrs_mut().insert(key.into(), value.into())
97 }
98
99 pub fn remove_attr(&mut self, key: &str) -> Option<Value> {
101 let attrs = self.attrs.as_mut()?;
102 let prev = attrs.remove(key);
103 if attrs.is_empty() {
104 self.attrs = None;
105 }
106 prev
107 }
108
109 #[inline]
113 pub fn child_count(&self) -> usize {
114 self.content.as_ref().map_or(0, Vec::len)
115 }
116
117 #[inline]
119 pub fn children(&self) -> &[Node] {
120 self.content.as_deref().unwrap_or(&[])
121 }
122
123 #[inline]
125 pub fn children_mut(&mut self) -> &mut Vec<Node> {
126 self.content.get_or_insert_with(Vec::new)
127 }
128
129 #[inline]
131 pub fn child(&self, i: usize) -> Option<&Node> {
132 self.content.as_ref()?.get(i)
133 }
134
135 #[inline]
137 pub fn child_mut(&mut self, i: usize) -> Option<&mut Node> {
138 self.content.as_mut()?.get_mut(i)
139 }
140
141 #[inline]
143 pub fn push_child(&mut self, node: Node) {
144 self.children_mut().push(node);
145 }
146
147 pub fn insert_child(&mut self, i: usize, node: Node) {
149 let children = self.children_mut();
150 let i = i.min(children.len());
151 children.insert(i, node);
152 }
153
154 pub fn remove_child(&mut self, i: usize) -> Option<Node> {
156 let children = self.content.as_mut()?;
157 if i >= children.len() {
158 return None;
159 }
160 let removed = children.remove(i);
161 if children.is_empty() {
162 self.content = None;
163 }
164 Some(removed)
165 }
166
167 pub fn replace_child(&mut self, i: usize, node: Node) -> Option<Node> {
169 let child = self.content.as_mut()?.get_mut(i)?;
170 Some(std::mem::replace(child, node))
171 }
172
173 pub fn clear_children(&mut self) {
175 self.content = None;
176 }
177
178 pub fn retain_children(&mut self, mut pred: impl FnMut(&Node) -> bool) {
180 if let Some(children) = self.content.as_mut() {
181 children.retain(|c| pred(c));
182 if children.is_empty() {
183 self.content = None;
184 }
185 }
186 }
187
188 #[inline]
192 pub fn get_text(&self) -> Option<&str> {
193 self.text.as_deref()
194 }
195
196 #[inline]
198 pub fn set_text(&mut self, text: impl Into<String>) {
199 self.text = Some(text.into());
200 }
201
202 pub fn replace_all(
206 &mut self,
207 mut pred: impl FnMut(&Node) -> bool,
208 mut f: impl FnMut(&mut Node),
209 ) -> usize {
210 let mut n = 0;
211 self.walk_mut(&mut |node| {
212 if pred(node) {
213 f(node);
214 n += 1;
215 }
216 });
217 n
218 }
219}