Skip to main content

apollo_federation/connectors/json_selection/
immutable.rs

1use std::clone::Clone;
2use std::rc::Rc;
3
4#[derive(Debug, Clone)]
5pub(crate) struct InputPath<T: Clone> {
6    path: Path<T>,
7}
8
9type Path<T> = Option<Rc<AppendPath<T>>>;
10
11#[derive(Debug, Clone)]
12struct AppendPath<T: Clone> {
13    prefix: Path<T>,
14    last: T,
15}
16
17impl<T: Clone> InputPath<T> {
18    pub(crate) const fn empty() -> Self {
19        Self { path: None }
20    }
21
22    pub(crate) fn append(&self, last: T) -> Self {
23        Self {
24            path: Some(Rc::new(AppendPath {
25                prefix: self.path.clone(),
26                last,
27            })),
28        }
29    }
30
31    pub(crate) fn to_vec(&self) -> Vec<T> {
32        // This method needs to be iterative rather than recursive, to be
33        // consistent with the paranoia of the drop method.
34        let mut vec = Vec::new();
35        let mut path = self.path.as_deref();
36        while let Some(p) = path {
37            vec.push(p.last.clone());
38            path = p.prefix.as_deref();
39        }
40        vec.reverse();
41        vec
42    }
43}
44
45impl<T: Clone> Drop for InputPath<T> {
46    fn drop(&mut self) {
47        let mut path = self.path.take();
48        while let Some(rc) = path {
49            if let Ok(mut p) = Rc::try_unwrap(rc) {
50                path = p.prefix.take();
51            } else {
52                break;
53            }
54        }
55    }
56}