syntree/builder/
checkpoint.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use core::cell::Cell;

use alloc::rc::Rc;

/// The identifier of a node as returned by functions such as
/// [`Builder::checkpoint`].
///
/// This can be used as a checkpoint in [`Builder::close_at`], and a checkpoint
/// can be fetched up front from [`Builder::checkpoint`].
///
/// [`Builder::close_at`]: crate::Builder::close_at
/// [`Builder::checkpoint`]: crate::Builder::checkpoint
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct Checkpoint<P>(Rc<Cell<Inner<P>>>)
where
    P: Copy;

impl<P> Checkpoint<P>
where
    P: Copy,
{
    pub(crate) fn new(node: P, parent: Option<P>) -> Self {
        Self(Rc::new(Cell::new(Inner { node, parent })))
    }

    pub(crate) fn set(&self, node: P, parent: Option<P>) {
        self.0.set(Inner { node, parent });
    }

    pub(crate) fn node(&self) -> P {
        self.0.get().node
    }

    pub(crate) fn get(&self) -> (P, Option<P>) {
        let Inner { node, parent } = self.0.get();
        (node, parent)
    }
}

/// The parent of the checkpoint.
#[derive(Debug, Clone, Copy)]
struct Inner<P> {
    // The node being wrapped by the checkpoint.
    node: P,
    // The parent node of the context being checkpointed.
    parent: Option<P>,
}