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