bracket/render/
scope.rs

1//! Scopes define the evaluation context for variable paths.
2use serde_json::{Map, Value};
3
4/// A scope encapsulates a base value (lookup object) used when
5/// resolving variable paths and a collection of local variables
6/// which are prefixed using the `@` symbol.
7///
8/// Helpers can create scopes and push and pop them from the scope
9/// stack to create new variable evaluation contexts.
10#[derive(Debug, Clone)]
11pub struct Scope {
12    value: Option<Value>,
13    locals: Value,
14}
15
16impl Scope {
17    /// Create a new scope.
18    pub fn new() -> Self {
19        Self {
20            locals: Value::Object(Map::new()),
21            value: None,
22        }
23    }
24
25    /// Get the underlying locals value.
26    pub fn locals(&self) -> &Value {
27        &self.locals
28    }
29
30    /// Set a named local variable.
31    ///
32    /// The name does not need an `@` prefix it is automatically
33    /// prepended to the key.
34    pub fn set_local(&mut self, name: &str, value: Value) {
35        self.locals
36            .as_object_mut()
37            .unwrap()
38            .insert(format!("@{}", name), value);
39    }
40
41    /// Get a named local.
42    ///
43    /// Locals should have the `@` prefix.
44    pub fn local(&self, name: &str) -> Option<&Value> {
45        self.locals.as_object().unwrap().get(name)
46    }
47
48    /// Set the base value for the scope.
49    ///
50    /// When the renderer resolves variables if they
51    /// can be resolved using this value they are preferred
52    /// over the root object.
53    pub fn set_base_value(&mut self, value: Value) {
54        self.value = Some(value);
55    }
56
57    /// Get the base value for this scope.
58    pub fn base_value(&self) -> &Option<Value> {
59        &self.value
60    }
61}
62
63/// Create a scope from hash parameters.
64impl From<Map<String, Value>> for Scope {
65    fn from(map: Map<String, Value>) -> Self {
66        let mut scope = Scope::new();
67        scope.value = Some(Value::Object(map));
68        scope
69    }
70}
71
72/// Create a scope from a context and hash parameters.
73impl From<(Value, Map<String, Value>)> for Scope {
74    fn from(value: (Value, Map<String, Value>)) -> Self {
75        let mut scope = Scope::new();
76        scope.value = Some(value.0);
77        scope.locals = Value::Object(value.1);
78        scope
79    }
80}