grit_pattern_matcher/pattern/
variable_content.rs

1use grit_util::error::{GritPatternError, GritResult};
2
3use super::{resolved_pattern::ResolvedPattern, state::State, variable::Variable};
4use crate::{context::QueryContext, pattern::patterns::Pattern};
5use std::borrow::Cow;
6
7#[derive(Debug, Clone)]
8pub struct VariableContent<'a, Q: QueryContext> {
9    pub name: String,
10    pub pattern: Option<&'a Pattern<Q>>,
11    // needs to be boxed for lifetime reasons
12    pub value: Option<Q::ResolvedPattern<'a>>,
13    pub value_history: Vec<Q::ResolvedPattern<'a>>,
14    // If the value is a binding, whenever it is updated the mirrors should be updated as well
15    pub mirrors: Vec<&'a Variable>,
16}
17
18impl<'a, Q: QueryContext> VariableContent<'a, Q> {
19    pub fn new(name: String) -> Self {
20        Self {
21            name,
22            pattern: None,
23            value: None,
24            value_history: vec![],
25            mirrors: vec![],
26        }
27    }
28
29    // should we return an option instead of a Result?
30    // should we trace pattern calls here? - currently only used by variable which already traces
31    pub fn text(
32        &self,
33        state: &State<'a, Q>,
34        language: &Q::Language<'a>,
35    ) -> GritResult<Cow<'a, str>> {
36        if let Some(value) = &self.value {
37            value.text(&state.files, language)
38        } else {
39            Err(GritPatternError::new(format!(
40                "no value for variable {}",
41                self.name
42            )))
43        }
44    }
45
46    pub(crate) fn set_value(&mut self, value: Q::ResolvedPattern<'a>) {
47        self.value = Some(value);
48    }
49}