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);
    }
}