darklua_core/process/processors/
find_identifier.rs

1use std::iter::FromIterator;
2
3use crate::{nodes::Identifier, process::NodeProcessor};
4
5/// A processor to find usage of a given set of identifiers.
6///
7/// # Example
8/// The following example illustrate how you can use this processor to find usage of the
9/// `foo` variable.
10/// ```
11/// # use darklua_core::nodes::Expression;
12/// # use darklua_core::process::processors::FindVariables;
13/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
14/// let variables = vec!["foo"];
15/// let mut find_foo: FindVariables = variables.into_iter().collect();
16///
17/// let mut foo_expression = Expression::identifier("foo");
18/// DefaultVisitor::visit_expression(&mut foo_expression, &mut find_foo);
19///
20/// assert!(find_foo.has_found_usage());
21/// ```
22/// If you pass a node that does not contain the given variable, the processor will return
23/// false when calling the `has_found_usage()` method.
24/// ```
25/// # use darklua_core::nodes::Expression;
26/// # use darklua_core::process::processors::FindVariables;
27/// # use darklua_core::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
28/// # let variables = vec!["foo"];
29/// # let mut find_foo: FindVariables = variables.into_iter().collect();
30/// let mut bar_expression = Expression::identifier("bar");
31/// DefaultVisitor::visit_expression(&mut bar_expression, &mut find_foo);
32///
33/// assert!(!find_foo.has_found_usage());
34/// ```
35pub struct FindVariables<'a> {
36    variables: Vec<&'a str>,
37    usage_found: bool,
38}
39
40impl<'a> FindVariables<'a> {
41    pub fn new(variable: &'a str) -> Self {
42        Self {
43            variables: vec![variable],
44            usage_found: false,
45        }
46    }
47
48    #[inline]
49    pub fn has_found_usage(&self) -> bool {
50        self.usage_found
51    }
52}
53
54impl<'a> FromIterator<&'a str> for FindVariables<'a> {
55    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
56        Self {
57            variables: iter.into_iter().collect(),
58            usage_found: false,
59        }
60    }
61}
62
63impl NodeProcessor for FindVariables<'_> {
64    fn process_variable_expression(&mut self, variable: &mut Identifier) {
65        if !self.usage_found {
66            let name = variable.get_name();
67            self.usage_found = self.variables.iter().any(|v| *v == name)
68        }
69    }
70}