1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
use alloc::vec::Vec; use alloc::string::String; use super::{Lines, State}; pub trait Input { fn peek(&mut self, state: &State, offset: usize) -> Option<char>; #[inline] fn read(&mut self, state: &mut State) -> Option<char> { match self.peek(state, 0) { Some(ch) => { state.read(ch == '\n'); Some(ch) }, None => None, } } #[inline] fn read_offset(&mut self, state: &mut State, offset: usize) { for _ in 0..offset { if self.read(state).is_none() { break; } } } #[inline] fn peek_line(&mut self, state: &State) -> String { let mut string = String::new(); let mut index = 0; while let Some(ch) = self.peek(state, index) { if ch != '\n' { index += 1; string.push(ch); } else { break; } } string } #[inline] fn read_line(&mut self, state: &mut State) -> String { let mut string = String::new(); while let Some(ch) = self.read(state) { if ch != '\n' { string.push(ch); } else { break; } } string } #[inline(always)] fn lines<'a>(&'a mut self, state: &'a mut State) -> Lines<'a, Self> { Lines::new(self, state) } #[inline(always)] fn done(&mut self, state: &State) -> bool { self.peek(state, 0).is_none() } #[inline(always)] fn can_read(&mut self, state: &State, offset: usize) -> bool { self.peek(state, offset).is_some() } } impl<'a> Input for &'a [char] { #[inline] fn peek(&mut self, state: &State, offset: usize) -> Option<char> { let index = state.index() + offset; if index < self.len() { Some(self[index]) } else { None } } } impl<'a> Input for &'a Vec<char> { #[inline(always)] fn peek(&mut self, state: &State, offset: usize) -> Option<char> { (&***self).peek(state, offset) } } impl Input for Vec<char> { #[inline(always)] fn peek(&mut self, state: &State, offset: usize) -> Option<char> { (&**self).peek(state, offset) } } #[cfg(test)] mod test { use super::*; #[test] fn test_input() { let mut state = State::new(); let mut input = "abc\ndef".chars().collect::<Vec<char>>(); input.read_offset(&mut state, 4); assert_eq!(input.peek(&mut state, 0), Some('d')); assert_eq!(input.peek(&mut state, 1), Some('e')); assert_eq!(input.peek(&mut state, 2), Some('f')); assert_eq!(state.index(), 4); assert_eq!(state.row(), 2); assert_eq!(state.col(), 1); } }