Skip to main content

gorrosion_gtp/input/
controller.rs

1use super::Byte;
2use super::{coerce_whitespace, discard};
3use std::iter;
4
5#[derive(Clone)]
6pub struct Input<'a> {
7	bytes: &'a [Byte],
8}
9
10impl<'a> Input<'a> {
11	#[doc(hidden)]
12	// TODO: This can probably made private with little effort
13	//       since most usages of this field
14	//       need to be moved in here anyway.
15	pub fn bytes(&self) -> &'a [Byte] {
16		self.bytes
17	}
18}
19
20impl<'a> From<&'a [Byte]> for Input<'a> {
21	fn from(bytes: &'a [Byte]) -> Self {
22		Input { bytes }
23	}
24}
25
26impl<'a> super::Input<'a> for Input<'a> {}
27
28pub struct Iterator<'a> {
29	bytes: &'a [Byte],
30	/// One more than the position of the last element that was output.
31	/// If we are not at the end of the iteration
32	/// and there are no discardable bytes,
33	/// it happens to be the position of the next element.
34	next: usize,
35}
36
37impl<'a> Iterator<'a> {
38	pub fn new(i: &Input<'a>) -> Self {
39		let bytes = i.bytes;
40		let next = 0;
41		Iterator { bytes, next }
42	}
43}
44
45impl<'a> iter::Iterator for Iterator<'a> {
46	type Item = Byte;
47
48	fn next(&mut self) -> Option<Self::Item> {
49		macro_rules! next_byte {
50			() => {
51				self.bytes[self.next]
52			};
53		}
54		if self.next >= self.bytes.len() {
55			None
56		} else if discard(next_byte!()) {
57			self.next += 1;
58			self.next()
59		} else {
60			let res = next_byte!();
61			self.next += 1;
62			Some(coerce_whitespace(res))
63		}
64	}
65}
66
67pub struct Enumerator<'a>(Iterator<'a>);
68
69impl<'a> Enumerator<'a> {
70	pub fn new(i: &Input<'a>) -> Self {
71		Enumerator(Iterator::new(i))
72	}
73}
74
75impl<'a> iter::Iterator for Enumerator<'a> {
76	type Item = (usize, Byte);
77
78	fn next(&mut self) -> Option<Self::Item> {
79		let Enumerator(iter) = self;
80		let byte = iter.next()?;
81		Some((iter.next - 1, byte))
82	}
83}