use crate::context::FeelContext;
use crate::values::Value;
use crate::{Name, QualifiedName};
use dmntk_common::Jsonify;
use std::cell::RefCell;
use std::fmt;
#[macro_export]
macro_rules! scope {
() => {{
FeelScope::default()
}};
}
pub struct FeelScope {
stack: RefCell<Vec<FeelContext>>,
}
impl Default for FeelScope {
fn default() -> Self {
Self {
stack: RefCell::new(vec![FeelContext::default()]),
}
}
}
impl From<FeelContext> for FeelScope {
fn from(ctx: FeelContext) -> Self {
Self { stack: RefCell::new(vec![ctx]) }
}
}
impl fmt::Display for FeelScope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}]", self.stack.borrow_mut().iter().map(|ctx| ctx.to_string()).collect::<Vec<String>>().join(", "))
}
}
impl Jsonify for FeelScope {
fn jsonify(&self) -> String {
format!("[{}]", self.stack.borrow_mut().iter().map(|ctx| ctx.to_string()).collect::<Vec<String>>().join(", "))
}
}
impl FeelScope {
pub fn contexts(&self) -> Vec<FeelContext> {
self.stack.borrow().clone()
}
pub fn new() -> Self {
Self { stack: RefCell::new(vec![]) }
}
pub fn push(&self, ctx: FeelContext) {
self.stack.borrow_mut().push(ctx)
}
pub fn append(&self, other: FeelScope) {
self.stack.borrow_mut().append(&mut other.stack.borrow_mut());
}
pub fn pop(&self) -> Option<FeelContext> {
self.stack.borrow_mut().pop()
}
pub fn peek(&self) -> Option<FeelContext> {
self.stack.borrow().last().cloned()
}
pub fn get_value(&self, name: &Name) -> Option<Value> {
for context in self.stack.borrow().iter().rev() {
if let Some(value) = context.get_entry(name) {
return Some(value.clone());
}
}
None
}
pub fn search(&self, names: &[Name]) -> Option<Value> {
for context in self.stack.borrow().iter().rev() {
if let Some(value) = context.search_deep(names) {
return Some(value.clone());
}
}
None
}
pub fn search_entry(&self, qname: &QualifiedName) -> Option<Value> {
for context in self.stack.borrow().iter().rev() {
if let Some(value) = context.search_entry(qname) {
return Some(value.clone());
}
}
None
}
pub fn set_value(&self, name: &Name, value: Value) {
if let Some(context) = self.stack.borrow_mut().last_mut() {
context.set_entry(name, value);
}
}
pub fn set_name(&self, name: Name) {
if let Some(context) = self.stack.borrow_mut().last_mut() {
context.set_null(name);
}
}
}