vte/
params.rs

1//! Fixed size parameters list with optional subparameters.
2
3use core::fmt::{self, Debug, Formatter};
4
5pub(crate) const MAX_PARAMS: usize = 32;
6
7#[derive(Default)]
8pub struct Params {
9    /// Number of subparameters for each parameter.
10    ///
11    /// For each entry in the `params` slice, this stores the length of the
12    /// param as number of subparams at the same index as the param in the
13    /// `params` slice.
14    ///
15    /// At the subparam positions the length will always be `0`.
16    subparams: [u8; MAX_PARAMS],
17
18    /// All parameters and subparameters.
19    params: [u16; MAX_PARAMS],
20
21    /// Number of suparameters in the current parameter.
22    current_subparams: u8,
23
24    /// Total number of parameters and subparameters.
25    len: usize,
26}
27
28impl Params {
29    /// Returns the number of parameters.
30    #[inline]
31    pub fn len(&self) -> usize {
32        self.len
33    }
34
35    /// Returns `true` if there are no parameters present.
36    #[inline]
37    pub fn is_empty(&self) -> bool {
38        self.len == 0
39    }
40
41    /// Returns an iterator over all parameters and subparameters.
42    #[inline]
43    pub fn iter(&self) -> ParamsIter<'_> {
44        ParamsIter::new(self)
45    }
46
47    /// Returns `true` if there is no more space for additional parameters.
48    #[inline]
49    pub(crate) fn is_full(&self) -> bool {
50        self.len == MAX_PARAMS
51    }
52
53    /// Clear all parameters.
54    #[inline]
55    pub(crate) fn clear(&mut self) {
56        self.current_subparams = 0;
57        self.len = 0;
58    }
59
60    /// Add an additional parameter.
61    #[inline]
62    pub(crate) fn push(&mut self, item: u16) {
63        self.subparams[self.len - self.current_subparams as usize] = self.current_subparams + 1;
64        self.params[self.len] = item;
65        self.current_subparams = 0;
66        self.len += 1;
67    }
68
69    /// Add an additional subparameter to the current parameter.
70    #[inline]
71    pub(crate) fn extend(&mut self, item: u16) {
72        self.subparams[self.len - self.current_subparams as usize] = self.current_subparams + 1;
73        self.params[self.len] = item;
74        self.current_subparams += 1;
75        self.len += 1;
76    }
77}
78
79impl<'a> IntoIterator for &'a Params {
80    type IntoIter = ParamsIter<'a>;
81    type Item = &'a [u16];
82
83    fn into_iter(self) -> Self::IntoIter {
84        self.iter()
85    }
86}
87
88/// Immutable subparameter iterator.
89pub struct ParamsIter<'a> {
90    params: &'a Params,
91    index: usize,
92}
93
94impl<'a> ParamsIter<'a> {
95    fn new(params: &'a Params) -> Self {
96        Self { params, index: 0 }
97    }
98}
99
100impl<'a> Iterator for ParamsIter<'a> {
101    type Item = &'a [u16];
102
103    fn next(&mut self) -> Option<Self::Item> {
104        if self.index >= self.params.len() {
105            return None;
106        }
107
108        // Get all subparameters for the current parameter.
109        let num_subparams = self.params.subparams[self.index];
110        let param = &self.params.params[self.index..self.index + num_subparams as usize];
111
112        // Jump to the next parameter.
113        self.index += num_subparams as usize;
114
115        Some(param)
116    }
117
118    fn size_hint(&self) -> (usize, Option<usize>) {
119        let remaining = self.params.len() - self.index;
120        (remaining, Some(remaining))
121    }
122}
123
124impl Debug for Params {
125    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
126        write!(f, "[")?;
127
128        for (i, param) in self.iter().enumerate() {
129            if i != 0 {
130                write!(f, ";")?;
131            }
132
133            for (i, subparam) in param.iter().enumerate() {
134                if i != 0 {
135                    write!(f, ":")?;
136                }
137
138                subparam.fmt(f)?;
139            }
140        }
141
142        write!(f, "]")
143    }
144}