1use crate::context::FeelContext;
4use crate::values::Value;
5use crate::{Name, QualifiedName};
6use dsntk_common::Jsonify;
7use std::cell::RefCell;
8use std::fmt;
9
10#[macro_export]
12macro_rules! scope {
13 () => {{
14 FeelScope::default()
15 }};
16}
17
18pub struct FeelScope {
20 stack: RefCell<Vec<FeelContext>>,
22}
23
24impl Default for FeelScope {
25 fn default() -> Self {
27 Self {
28 stack: RefCell::new(vec![FeelContext::default()]),
29 }
30 }
31}
32
33impl From<FeelContext> for FeelScope {
34 fn from(ctx: FeelContext) -> Self {
36 Self { stack: RefCell::new(vec![ctx]) }
37 }
38}
39
40impl fmt::Display for FeelScope {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(f, "[{}]", self.stack.borrow_mut().iter().map(|ctx| ctx.to_string()).collect::<Vec<String>>().join(", "))
44 }
45}
46
47impl Jsonify for FeelScope {
48 fn jsonify(&self) -> String {
50 format!("[{}]", self.stack.borrow_mut().iter().map(|ctx| ctx.to_string()).collect::<Vec<String>>().join(", "))
51 }
52}
53
54impl FeelScope {
55 pub fn contexts(&self) -> Vec<FeelContext> {
57 self.stack.borrow().clone()
58 }
59
60 pub fn new() -> Self {
62 Self { stack: RefCell::new(vec![]) }
63 }
64
65 pub fn push(&self, ctx: FeelContext) {
67 self.stack.borrow_mut().push(ctx)
68 }
69
70 pub fn append(&self, other: FeelScope) {
72 self.stack.borrow_mut().append(&mut other.stack.borrow_mut());
73 }
74
75 pub fn pop(&self) -> Option<FeelContext> {
77 self.stack.borrow_mut().pop()
78 }
79
80 pub fn peek(&self) -> Option<FeelContext> {
83 self.stack.borrow().last().cloned()
84 }
85
86 pub fn get_value(&self, name: &Name) -> Option<Value> {
90 for context in self.stack.borrow().iter().rev() {
91 if let Some(value) = context.get_entry(name) {
92 return Some(value.clone());
93 }
94 }
95 None
96 }
97
98 pub fn search(&self, names: &[Name]) -> Option<Value> {
101 for context in self.stack.borrow().iter().rev() {
102 if let Some(value) = context.search_deep(names) {
103 return Some(value.clone());
104 }
105 }
106 None
107 }
108
109 pub fn search_entry(&self, qname: &QualifiedName) -> Option<Value> {
111 for context in self.stack.borrow().iter().rev() {
112 if let Some(value) = context.search_entry(qname) {
113 return Some(value.clone());
114 }
115 }
116 None
117 }
118
119 pub fn set_value(&self, name: &Name, value: Value) {
121 if let Some(context) = self.stack.borrow_mut().last_mut() {
122 context.set_entry(name, value);
123 }
124 }
125
126 pub fn set_name(&self, name: Name) {
128 if let Some(context) = self.stack.borrow_mut().last_mut() {
129 context.set_null(name);
130 }
131 }
132}