1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::process::NodeProcessor;

/// A processor to find usage of a given set of identifiers.
///
/// # Example
/// The following example illustrate how you can use this processor to find usage of the
/// `foo` variable.
/// ```
/// # use darklua_core::nodes::Expression;
/// # use darklua_core::process::processors::FindVariables;
/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
/// let variables = vec!["foo".to_owned()];
/// let mut find_foo = FindVariables::from(&variables);
///
/// let mut foo_expression = Expression::Identifier("foo".to_owned());
/// DefaultVisitor::visit_expression(&mut foo_expression, &mut find_foo);
///
/// assert!(find_foo.has_found_usage());
/// ```
/// If you pass a node that does not contain the given variable, the processor will return
/// false when calling the `has_found_usage()` method.
/// ```
/// # use darklua_core::nodes::Expression;
/// # use darklua_core::process::processors::FindVariables;
/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
/// # let variables = vec!["foo".to_owned()];
/// # let mut find_foo = FindVariables::from(&variables);
/// let mut bar_expression = Expression::Identifier("bar".to_owned());
/// DefaultVisitor::visit_expression(&mut bar_expression, &mut find_foo);
///
/// assert!(!find_foo.has_found_usage());
/// ```
pub struct FindVariables<'a> {
    variables: &'a Vec<String>,
    usage_found: bool,
}

impl<'a> FindVariables<'a> {
    #[inline]
    pub fn has_found_usage(&self) -> bool {
        self.usage_found
    }
}

impl<'a> From<&'a Vec<String>> for FindVariables<'a> {
    fn from(variables: &'a Vec<String>) -> Self {
        Self {
            variables,
            usage_found: false,
        }
    }
}

impl<'a> NodeProcessor for FindVariables<'a> {
    fn process_variable_expression(&mut self, variable: &mut String) {
        if !self.usage_found {
            self.usage_found = self.variables.iter().any(|v| v == variable)
        }
    }
}