Skip to content

Commit 1651757

Browse files
committed
Provide consuming movement methods so that NodeMut can act as a cursor.
1 parent 30bdf56 commit 1651757

File tree

2 files changed

+82
-25
lines changed

2 files changed

+82
-25
lines changed

src/lib.rs

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -247,39 +247,36 @@ impl<'a, T: 'a> NodeRef<'a, T> {
247247
&self.node.value
248248
}
249249

250+
fn axis<F>(&self, f: F) -> Option<Self>
251+
where
252+
F: FnOnce(&Node<T>) -> Option<NodeId>,
253+
{
254+
f(self.node).map(|id| unsafe { self.tree.get_unchecked(id) })
255+
}
256+
250257
/// Returns the parent of this node.
251258
pub fn parent(&self) -> Option<Self> {
252-
self.node
253-
.parent
254-
.map(|id| unsafe { self.tree.get_unchecked(id) })
259+
self.axis(|node| node.parent)
255260
}
256261

257262
/// Returns the previous sibling of this node.
258263
pub fn prev_sibling(&self) -> Option<Self> {
259-
self.node
260-
.prev_sibling
261-
.map(|id| unsafe { self.tree.get_unchecked(id) })
264+
self.axis(|node| node.prev_sibling)
262265
}
263266

264267
/// Returns the next sibling of this node.
265268
pub fn next_sibling(&self) -> Option<Self> {
266-
self.node
267-
.next_sibling
268-
.map(|id| unsafe { self.tree.get_unchecked(id) })
269+
self.axis(|node| node.next_sibling)
269270
}
270271

271272
/// Returns the first child of this node.
272273
pub fn first_child(&self) -> Option<Self> {
273-
self.node
274-
.children
275-
.map(|(id, _)| unsafe { self.tree.get_unchecked(id) })
274+
self.axis(|node| node.children.map(|(id, _)| id))
276275
}
277276

278277
/// Returns the last child of this node.
279278
pub fn last_child(&self) -> Option<Self> {
280-
self.node
281-
.children
282-
.map(|(_, id)| unsafe { self.tree.get_unchecked(id) })
279+
self.axis(|node| node.children.map(|(_, id)| id))
283280
}
284281

285282
/// Returns true if this node has siblings.
@@ -313,34 +310,70 @@ impl<'a, T: 'a> NodeMut<'a, T> {
313310
&mut self.node().value
314311
}
315312

313+
fn axis<F>(&mut self, f: F) -> Option<NodeMut<T>>
314+
where
315+
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
316+
{
317+
let id = f(self.node());
318+
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
319+
}
320+
321+
fn into_axis<F>(mut self, f: F) -> Option<Self>
322+
where
323+
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
324+
{
325+
let id = f(self.node());
326+
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
327+
}
328+
316329
/// Returns the parent of this node.
317330
pub fn parent(&mut self) -> Option<NodeMut<T>> {
318-
let id = self.node().parent;
319-
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
331+
self.axis(|node| node.parent)
332+
}
333+
334+
/// Returns the parent of this node.
335+
pub fn into_parent(self) -> Option<Self> {
336+
self.into_axis(|node| node.parent)
320337
}
321338

322339
/// Returns the previous sibling of this node.
323340
pub fn prev_sibling(&mut self) -> Option<NodeMut<T>> {
324-
let id = self.node().prev_sibling;
325-
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
341+
self.axis(|node| node.prev_sibling)
342+
}
343+
344+
/// Returns the previous sibling of this node.
345+
pub fn into_prev_sibling(self) -> Option<Self> {
346+
self.into_axis(|node| node.prev_sibling)
326347
}
327348

328349
/// Returns the next sibling of this node.
329350
pub fn next_sibling(&mut self) -> Option<NodeMut<T>> {
330-
let id = self.node().next_sibling;
331-
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
351+
self.axis(|node| node.next_sibling)
352+
}
353+
354+
/// Returns the next sibling of this node.
355+
pub fn into_next_sibling(self) -> Option<Self> {
356+
self.into_axis(|node| node.next_sibling)
332357
}
333358

334359
/// Returns the first child of this node.
335360
pub fn first_child(&mut self) -> Option<NodeMut<T>> {
336-
let ids = self.node().children;
337-
ids.map(move |(id, _)| unsafe { self.tree.get_unchecked_mut(id) })
361+
self.axis(|node| node.children.map(|(id, _)| id))
362+
}
363+
364+
/// Returns the first child of this node.
365+
pub fn into_first_child(self) -> Option<Self> {
366+
self.into_axis(|node| node.children.map(|(id, _)| id))
338367
}
339368

340369
/// Returns the last child of this node.
341370
pub fn last_child(&mut self) -> Option<NodeMut<T>> {
342-
let ids = self.node().children;
343-
ids.map(move |(_, id)| unsafe { self.tree.get_unchecked_mut(id) })
371+
self.axis(|node| node.children.map(|(_, id)| id))
372+
}
373+
374+
/// Returns the last child of this node.
375+
pub fn into_last_child(self) -> Option<Self> {
376+
self.into_axis(|node| node.children.map(|(_, id)| id))
344377
}
345378

346379
/// Returns true if this node has siblings.

tests/node_mut.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,30 @@ fn insert_after() {
277277
assert_eq!(None, d.next_sibling());
278278
}
279279

280+
#[test]
281+
fn insert_at_index() {
282+
let mut tree = tree!('a' => { 'b', 'c', 'e' });
283+
284+
{
285+
let mut root = tree.root_mut();
286+
let mut child = root.first_child().unwrap();
287+
288+
for _ in 0..2 {
289+
child = child.into_next_sibling().unwrap();
290+
}
291+
292+
child.insert_before('d');
293+
}
294+
295+
let descendants = tree
296+
.root()
297+
.descendants()
298+
.map(|n| n.value())
299+
.collect::<Vec<_>>();
300+
301+
assert_eq!(&[&'a', &'b', &'c', &'d', &'e',], &descendants[..]);
302+
}
303+
280304
#[test]
281305
fn detach() {
282306
let mut tree = tree!('a' => { 'b', 'd' });

0 commit comments

Comments
 (0)