Skip to content

Commit 65df834

Browse files
authored
Merge pull request #33 from adamreichold/node-mut-cursor
Provide consuming movement methods so that NodeMut can act as a cursor.
2 parents 15c84e9 + 118d629 commit 65df834

File tree

2 files changed

+100
-25
lines changed

2 files changed

+100
-25
lines changed

src/lib.rs

+76-25
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,88 @@ 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) -> Result<Self, Self>
322+
where
323+
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
324+
{
325+
let id = f(self.node());
326+
match id {
327+
Some(id) => Ok(unsafe { self.tree.get_unchecked_mut(id) }),
328+
None => Err(self),
329+
}
330+
}
331+
316332
/// Returns the parent of this node.
317333
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) })
334+
self.axis(|node| node.parent)
335+
}
336+
337+
/// Returns the parent of this node.
338+
///
339+
/// Returns `Ok(parent)` if possible and `Err(self)` otherwise
340+
/// so the caller can recover the current position.
341+
pub fn into_parent(self) -> Result<Self, Self> {
342+
self.into_axis(|node| node.parent)
320343
}
321344

322345
/// Returns the previous sibling of this node.
323346
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) })
347+
self.axis(|node| node.prev_sibling)
348+
}
349+
350+
/// Returns the previous sibling of this node.
351+
///
352+
/// Returns `Ok(prev_sibling)` if possible and `Err(self)` otherwise
353+
/// so the caller can recover the current position.
354+
pub fn into_prev_sibling(self) -> Result<Self, Self> {
355+
self.into_axis(|node| node.prev_sibling)
326356
}
327357

328358
/// Returns the next sibling of this node.
329359
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) })
360+
self.axis(|node| node.next_sibling)
361+
}
362+
363+
/// Returns the next sibling of this node.
364+
///
365+
/// Returns `Ok(next_sibling)` if possible and `Err(self)` otherwise
366+
/// so the caller can recover the current position.
367+
pub fn into_next_sibling(self) -> Result<Self, Self> {
368+
self.into_axis(|node| node.next_sibling)
332369
}
333370

334371
/// Returns the first child of this node.
335372
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) })
373+
self.axis(|node| node.children.map(|(id, _)| id))
374+
}
375+
376+
/// Returns the first child of this node.
377+
///
378+
/// Returns `Ok(first_child)` if possible and `Err(self)` otherwise
379+
/// so the caller can recover the current position.
380+
pub fn into_first_child(self) -> Result<Self, Self> {
381+
self.into_axis(|node| node.children.map(|(id, _)| id))
338382
}
339383

340384
/// Returns the last child of this node.
341385
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) })
386+
self.axis(|node| node.children.map(|(_, id)| id))
387+
}
388+
389+
/// Returns the last child of this node.
390+
///
391+
/// Returns `Ok(last_child)` if possible and `Err(self)` otherwise
392+
/// so the caller can recover the current position.
393+
pub fn into_last_child(self) -> Result<Self, Self> {
394+
self.into_axis(|node| node.children.map(|(_, id)| id))
344395
}
345396

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

tests/node_mut.rs

+24
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)