syntree/builder/
checkpoint.rs

1use core::cell::Cell;
2
3use alloc::rc::Rc;
4
5/// The identifier of a node as returned by functions such as
6/// [`Builder::checkpoint`].
7///
8/// This can be used as a checkpoint in [`Builder::close_at`], and a checkpoint
9/// can be fetched up front from [`Builder::checkpoint`].
10///
11/// [`Builder::close_at`]: crate::Builder::close_at
12/// [`Builder::checkpoint`]: crate::Builder::checkpoint
13#[derive(Debug, Clone)]
14#[repr(transparent)]
15pub struct Checkpoint<P>(Rc<Cell<Inner<P>>>)
16where
17    P: Copy;
18
19impl<P> Checkpoint<P>
20where
21    P: Copy,
22{
23    pub(crate) fn new(node: P, parent: Option<P>) -> Self {
24        Self(Rc::new(Cell::new(Inner { node, parent })))
25    }
26
27    pub(crate) fn set(&self, node: P, parent: Option<P>) {
28        self.0.set(Inner { node, parent });
29    }
30
31    pub(crate) fn node(&self) -> P {
32        self.0.get().node
33    }
34
35    pub(crate) fn get(&self) -> (P, Option<P>) {
36        let Inner { node, parent } = self.0.get();
37        (node, parent)
38    }
39}
40
41/// The parent of the checkpoint.
42#[derive(Debug, Clone, Copy)]
43struct Inner<P> {
44    // The node being wrapped by the checkpoint.
45    node: P,
46    // The parent node of the context being checkpointed.
47    parent: Option<P>,
48}