Skip to main content

linkrs_query/binder/
scope.rs

1use std::collections::HashMap;
2use std::rc::Rc;
3
4use linkrs_core::types::semantic::{AliasType, ValueType};
5
6#[derive(Debug, Clone)]
7pub struct BinderVariable {
8    pub name: String,
9    pub alias_type: AliasType,
10    pub tags: Vec<String>,
11    pub properties: HashMap<String, ValueType>,
12    pub is_defined: bool,
13}
14
15#[derive(Debug, Clone)]
16pub struct BinderScope {
17    variables: HashMap<String, BinderVariable>,
18    parent: Option<Rc<BinderScope>>,
19}
20
21impl BinderScope {
22    pub fn new() -> Self {
23        Self {
24            variables: HashMap::new(),
25            parent: None,
26        }
27    }
28
29    pub fn with_parent(parent: BinderScope) -> Self {
30        Self {
31            variables: HashMap::new(),
32            parent: Some(Rc::new(parent)),
33        }
34    }
35
36    pub fn define_variable(&mut self, var: BinderVariable) {
37        self.variables.insert(var.name.clone(), var);
38    }
39
40    pub fn lookup(&self, name: &str) -> Option<&BinderVariable> {
41        self.variables
42            .get(name)
43            .or_else(|| self.parent.as_ref().and_then(|p| p.lookup(name)))
44    }
45
46    pub fn contains(&self, name: &str) -> bool {
47        self.variables.contains_key(name) || self.parent.as_ref().is_some_and(|p| p.contains(name))
48    }
49
50    pub fn all_variables(&self) -> Vec<&BinderVariable> {
51        let mut vars: Vec<_> = self.variables.values().collect();
52        if let Some(ref parent) = self.parent {
53            vars.extend(parent.all_variables());
54        }
55        vars
56    }
57}
58
59impl Default for BinderScope {
60    fn default() -> Self {
61        Self::new()
62    }
63}