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