kernel/cmdline/
tokenizer.rs

1pub struct Tokenizer<'a> {
2    running_str: &'a str,
3    idx: usize,
4}
5
6impl<'a> Tokenizer<'a> {
7    pub fn new(inp: &'a str) -> Self {
8        Self {
9            running_str: inp,
10            idx: 0,
11        }
12    }
13
14    pub fn current_index(&self) -> usize {
15        self.idx
16    }
17
18    fn next_token<P1, P2, P3>(
19        &mut self,
20        find_pattern: P1,
21        starts_with_pattern: P2,
22        strip_pattern: P3,
23    ) -> Option<(usize, &'a str)>
24    where
25        P1: FnMut(char) -> bool,
26        P2: FnMut(char) -> bool,
27        P3: FnMut(char) -> bool,
28    {
29        if self.running_str.is_empty() {
30            return None;
31        }
32
33        let i = self.running_str.find(find_pattern)?;
34
35        let (value, rest) = self.running_str.split_at(i);
36
37        if value.is_empty() {
38            return None;
39        }
40
41        let rest_len = rest.len();
42
43        self.running_str = rest
44            .strip_prefix(starts_with_pattern)?
45            .trim_start_matches(strip_pattern);
46
47        let old_value_len = value.len();
48        let value = value.trim_start();
49
50        let leading_whitespace_size = value.len() - old_value_len;
51        let pos_start = self.idx + leading_whitespace_size;
52        self.idx += i + (rest_len - self.running_str.len());
53
54        Some((pos_start, value.trim_end()))
55    }
56
57    pub fn next_ident(&mut self) -> Option<(usize, &'a str)> {
58        self.next_token(
59            |c| !c.is_alphanumeric() && c != ',' && c != '_',
60            |c| c == '=',
61            |c| c.is_whitespace(),
62        )
63    }
64
65    pub fn next_value(&mut self) -> Option<(usize, &'a str)> {
66        self.next_token(
67            |c| c.is_whitespace() || c == ',' || c == '=',
68            |c| c.is_whitespace() || c == ',',
69            |c| c.is_whitespace() || c == ',',
70        )
71        .or_else(|| {
72            let rest = self.running_str;
73            self.running_str = "";
74            let pos_start = self.idx;
75            self.idx += rest.len();
76            Some((pos_start, rest))
77        })
78    }
79}