asn1_rs/
input.rs

1#[cfg(not(feature = "std"))]
2use alloc::string::String;
3use alloc::vec::Vec;
4use core::fmt;
5use core::iter::{Cloned, Enumerate};
6use core::ops::Range;
7use core::slice::Iter;
8
9use nom::{AsBytes, Needed};
10
11/// BER/DER parser input type
12#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
13pub struct Input<'a> {
14    data: &'a [u8],
15    span: Range<usize>,
16}
17
18impl<'a> Input<'a> {
19    /// Build a new `Input``
20    #[inline]
21    pub const fn new(data: &'a [u8], span: Range<usize>) -> Self {
22        Self { data, span }
23    }
24
25    #[inline]
26    pub const fn from_slice(data: &'a [u8]) -> Self {
27        let span = Range {
28            start: 0,
29            end: data.len(),
30        };
31        Self { data, span }
32    }
33
34    #[inline]
35    pub const fn const_clone(&self) -> Self {
36        Self {
37            data: self.data,
38            span: Range {
39                start: self.span.start,
40                end: self.span.end,
41            },
42        }
43    }
44
45    #[inline]
46    pub const fn span(&self) -> &Range<usize> {
47        &self.span
48    }
49
50    #[inline]
51    pub const fn start(&self) -> usize {
52        self.span.start
53    }
54
55    #[inline]
56    pub const fn end(&self) -> usize {
57        self.span.end
58    }
59
60    #[inline]
61    pub const fn len(&self) -> usize {
62        self.data.len()
63    }
64
65    #[inline]
66    pub const fn is_empty(&self) -> bool {
67        self.data.is_empty()
68    }
69
70    // see https://users.rust-lang.org/t/returning-data-from-ephemeral-object/125787/1
71    #[inline]
72    pub const fn as_bytes2(&self) -> &'a [u8] {
73        self.data
74    }
75
76    #[inline]
77    pub const fn into_bytes(self) -> &'a [u8] {
78        self.data
79    }
80}
81
82impl<'a> AsRef<[u8]> for Input<'a> {
83    fn as_ref(&self) -> &'a [u8] {
84        self.data
85    }
86}
87
88impl<'a> AsBytes for Input<'a> {
89    fn as_bytes(&self) -> &'a [u8] {
90        self.data
91    }
92}
93
94impl<'a> From<&'a [u8]> for Input<'a> {
95    fn from(data: &'a [u8]) -> Self {
96        Input {
97            data,
98            span: Range {
99                start: 0,
100                end: data.len(),
101            },
102        }
103    }
104}
105
106impl<'a, const N: usize> From<&'a [u8; N]> for Input<'a> {
107    fn from(value: &'a [u8; N]) -> Self {
108        let s = value.as_slice();
109        Self::from(s)
110    }
111}
112
113impl<'a> From<&'a Vec<u8>> for Input<'a> {
114    fn from(data: &'a Vec<u8>) -> Self {
115        Input {
116            data,
117            span: Range {
118                start: 0,
119                end: data.len(),
120            },
121        }
122    }
123}
124
125impl fmt::Display for Input<'_> {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        write!(f, "Input(start={} end={})", self.start(), self.end())
128    }
129}
130
131impl<'a> nom::Input for Input<'a> {
132    type Item = u8;
133
134    type Iter = Cloned<Iter<'a, u8>>;
135
136    type IterIndices = Enumerate<Self::Iter>;
137
138    fn input_len(&self) -> usize {
139        self.data.len()
140    }
141
142    fn take(&self, index: usize) -> Self {
143        let fragment = &self.data[..index];
144        let span = Range {
145            start: self.span.start,
146            end: self.span.start + index,
147        };
148        Self::new(fragment, span)
149    }
150
151    fn take_from(&self, index: usize) -> Self {
152        let fragment = &self.data[index..];
153        let span = Range {
154            start: self.span.start + index,
155            end: self.span.end,
156        };
157        Self::new(fragment, span)
158    }
159
160    fn take_split(&self, index: usize) -> (Self, Self) {
161        (self.take_from(index), self.take(index))
162    }
163
164    fn position<P>(&self, predicate: P) -> Option<usize>
165    where
166        P: Fn(Self::Item) -> bool,
167    {
168        self.data.position(predicate)
169    }
170
171    fn iter_elements(&self) -> Self::Iter {
172        self.data.iter().cloned()
173    }
174
175    fn iter_indices(&self) -> Self::IterIndices {
176        self.iter_elements().enumerate()
177    }
178
179    fn slice_index(&self, count: usize) -> Result<usize, Needed> {
180        if self.data.len() >= count {
181            Ok(count)
182        } else {
183            Err(Needed::new(count - self.data.len()))
184        }
185    }
186}
187
188impl nom::HexDisplay for Input<'_> {
189    fn to_hex(&self, chunk_size: usize) -> String {
190        self.data.to_hex(chunk_size)
191    }
192
193    fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
194        self.data.to_hex_from(chunk_size, from)
195    }
196}
197
198#[cfg(test)]
199mod tests {
200    use core::ops::Range;
201
202    use hex_literal::hex;
203    use nom::Input as _;
204
205    use super::Input;
206
207    #[test]
208    fn input_take() {
209        let data = &hex!("00 01 02 03 04 05");
210        let input = Input::from(data);
211
212        let r = input.take(2);
213        assert_eq!(r, Input::new(&data[..2], Range { start: 0, end: 2 }));
214
215        let r = input.take_from(2);
216        assert_eq!(r, Input::new(&data[2..], Range { start: 2, end: 6 }));
217
218        let r = input.iter_elements();
219        assert!(r.eq(0..6));
220
221        let r = input.iter_indices();
222        assert!(r.eq((0..6).enumerate()));
223    }
224}