1use regex::Regex;
7use std::collections::HashMap;
8
9use super::{VarEntry, VarType, VarsFile};
10
11pub struct VarResolver {
13 vars: HashMap<String, VarEntry>,
14 var_pattern: Regex,
15}
16
17impl VarResolver {
18 pub fn new(vars_file: VarsFile) -> Self {
20 Self {
21 vars: vars_file.variables,
22 var_pattern: Regex::new(r"\$([A-Z][A-Z0-9_]+)(?:\.(\w+))?").unwrap(),
23 }
24 }
25
26 pub fn get(&self, name: &str) -> Option<&VarEntry> {
28 self.vars.get(name)
29 }
30
31 pub fn find_references(&self, text: &str) -> Vec<VarReference> {
33 self.var_pattern
34 .captures_iter(text)
35 .map(|cap| VarReference {
36 full_match: cap.get(0).unwrap().as_str().to_string(),
37 name: cap.get(1).unwrap().as_str().to_string(),
38 modifier: cap.get(2).map(|m| m.as_str().to_string()),
39 start: cap.get(0).unwrap().start(),
40 end: cap.get(0).unwrap().end(),
41 })
42 .collect()
43 }
44
45 pub fn by_type(&self, var_type: VarType) -> Vec<&VarEntry> {
47 self.vars
48 .values()
49 .filter(|v| v.var_type == var_type)
50 .collect()
51 }
52
53 pub fn search(&self, query: &str) -> Vec<&VarEntry> {
55 let q = query.to_lowercase();
56 self.vars
57 .values()
58 .filter(|v| {
59 v.value.to_lowercase().contains(&q)
60 || v.description
61 .as_ref()
62 .map(|s| s.to_lowercase().contains(&q))
63 .unwrap_or(false)
64 })
65 .collect()
66 }
67}
68
69#[derive(Debug, Clone)]
71pub struct VarReference {
72 pub full_match: String,
73 pub name: String,
74 pub modifier: Option<String>,
75 pub start: usize,
76 pub end: usize,
77}