linkrs_query/binder/
scope.rs1use 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}