json_ld_context_processing/
stack.rs1use std::sync::Arc;
2
3struct StackNode<I> {
5 previous: Option<Arc<StackNode<I>>>,
7
8 url: I,
10}
11
12impl<I> StackNode<I> {
13 fn new(previous: Option<Arc<StackNode<I>>>, url: I) -> StackNode<I> {
15 StackNode { previous, url }
16 }
17
18 fn contains(&self, url: &I) -> bool
20 where
21 I: PartialEq,
22 {
23 if self.url == *url {
24 true
25 } else {
26 match &self.previous {
27 Some(prev) => prev.contains(url),
28 None => false,
29 }
30 }
31 }
32}
33
34#[derive(Clone)]
38pub struct ProcessingStack<I> {
39 head: Option<Arc<StackNode<I>>>,
40}
41
42impl<I> ProcessingStack<I> {
43 pub fn new() -> Self {
45 Self { head: None }
46 }
47
48 pub fn is_empty(&self) -> bool {
50 self.head.is_none()
51 }
52
53 pub fn cycle(&self, url: &I) -> bool
57 where
58 I: PartialEq,
59 {
60 match &self.head {
61 Some(head) => head.contains(url),
62 None => false,
63 }
64 }
65
66 pub fn push(&mut self, url: I) -> bool
71 where
72 I: PartialEq,
73 {
74 if self.cycle(&url) {
75 false
76 } else {
77 let mut head = None;
78 std::mem::swap(&mut head, &mut self.head);
79 self.head = Some(Arc::new(StackNode::new(head, url)));
80 true
81 }
82 }
83}
84
85impl<I> Default for ProcessingStack<I> {
86 fn default() -> Self {
87 Self::new()
88 }
89}