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
mod types; mod utils; pub use utils::*; use std::fmt::Debug; use std::rc::Rc; #[derive(Debug, Clone, Copy)] pub enum State { Begin, Continue, End, Unknown, } #[derive(Debug, Clone)] pub enum Line<T: Clone> { Line(usize, T, State), LineDepth(usize, T, State, usize), Unknown, Skip, SkipCount, } impl<T: Clone> Line<T> { pub fn begin(line_num: usize, token: T) -> Self { Self::Line(line_num, token, State::Begin) } pub fn cont(line_num: usize, token: T) -> Self { Self::Line(line_num, token, State::Continue) } pub fn end(line_num: usize, token: T) -> Self { Self::Line(line_num, token, State::End) } pub fn set_state(&mut self, state: State) { if let Line::Line(ln, t, _) = &*self { *self = Line::Line(*ln, t.clone(), state); } } pub fn update(&mut self, line_num: usize, line: &str) {} } pub type HandleLine<T> = dyn Fn(Option<&Line<T>>, usize, &str) -> Line<T>; pub fn parser<T: Clone>(f: &'static HandleLine<T>) -> Parser<T> { Parser::new(Rc::new(f)) } pub struct Parser<T: Clone> { handle_line: Rc<HandleLine<T>>, } impl<T: Clone> Parser<T> { pub fn new(f: Rc<HandleLine<T>>) -> Self { Self { handle_line: f } } pub fn parse<'a>(&mut self, data: &'a str) -> std::str::Lines<'a> { data.lines() } pub fn iter<'a>(&mut self, data: &'a str) -> TydIterator<'a, T> { TydIterator::new(self.handle_line.clone(), data.lines().enumerate()) } } pub struct TydIterator<'a, T: Clone> { parser: Rc<HandleLine<T>>, last_line: Option<Line<T>>, lines: std::iter::Enumerate<std::str::Lines<'a>>, } impl<'a, T: Clone> TydIterator<'a, T> { fn new(parser: Rc<HandleLine<T>>, lines: std::iter::Enumerate<std::str::Lines<'a>>) -> Self { Self { parser, last_line: None, lines, } } } impl<'a, T: Clone + Debug> Iterator for TydIterator<'a, T> { type Item = (Line<T>, &'a str); fn next(&mut self) -> Option<Self::Item> { if let Some((i, line)) = self.lines.next() { let line_state = (self.parser)(self.last_line.as_ref(), i, line); if let Line::SkipCount = line_state { } else { self.last_line = Some(line_state.clone()); } return Some((line_state, line)); } None } }