use std::io; use tyd::*; #[derive(Debug, Clone)] pub enum Token { Struct(String), Use(String), Derive(String), Module(String), None, } fn find_use() {} fn parse_nested_use(s: &String, i: usize, line: &str, depth: usize) -> Line { let line = line.trim(); if line.is_empty() { return Line::LineDepth(i, Token::Use(s.to_string()), State::Continue, depth); } let s = s.to_string() + line; if ends_with(line, &["}", "},", ",}"]) { let depth_count = rcount_ends_with(line, &["}", "},", ",}"]); if depth > 0 { if depth - (depth_count - 1) == 0 { return Line::LineDepth( i, Token::Use(s.to_string()), State::End, depth - (depth_count - 1), ); } return Line::LineDepth( i, Token::Use(s.to_string()), State::Continue, depth - depth_count, ); } else { return Line::LineDepth(i, Token::Use(s.to_string()), State::End, 0); } } else if ends_with(line, &["{", "{,", ",{"]) { let depth_count = rcount_ends_with(line, &["{", "{,", ",{"]); return Line::LineDepth( i, Token::Use(s.to_string()), State::Continue, depth + depth_count, ); } else { return Line::LineDepth(i, Token::Use(s), State::Continue, depth); } } fn parse_derive(s: &String, i: usize, line: &str) -> Line { Line::Skip } fn parse_nested_module(s: &String, i: usize, line: &str, depth: usize) -> Line { let line = line.trim(); if line.is_empty() { return Line::LineDepth(i, Token::Module(s.to_string()), State::Continue, depth); } let s = s.to_string() + line; if ends_with(line, &["}"]) { let depth_count = rcount_ends_with(line, &["}"]); //println!("{:?} {:?}", depth, depth_count - 1); if depth > 0 { if depth - (depth_count - 1) == 0 { return Line::LineDepth( i, Token::Module(s.to_string()), State::End, depth - (depth_count - 1), ); } return Line::LineDepth( i, Token::Module(s.to_string()), State::Continue, depth - depth_count, ); } else { return Line::LineDepth(i, Token::Module(s.to_string()), State::End, 0); } } else if ends_with(line, &["{", "{,", ",{"]) { return line_starts_with(i, line, depth + 1); /* let depth_count = rcount_ends_with(line, &["{", "{,", ",{"]); return Line::LineDepth( i, Token::Module(s.to_string()), State::Continue, depth + depth_count, ); */ } else { return line_starts_with(i, line, depth + 1); //return Line::LineDepth(i, Token::Module(s), State::Continue, depth); } } fn parse_struct(i: usize, line: &str) -> Line { Line::Line(i, Token::Struct(line.to_string()), State::End) } fn line_starts_with(i: usize, line: &str, depth: usize) -> Line { if starts_with(line, &[":use {", ":use{"]) && line.ends_with('}') { return Line::LineDepth(i, Token::Use(String::from(line)), State::End, 0); } else if starts_with(line, &[":use {", ":use{"]) { return Line::LineDepth(i, Token::Use(String::new()), State::Begin, 0); } else if line.starts_with(":derive") && line.ends_with(')') { return Line::Line(i, Token::Derive(line[7..].trim().to_string()), State::End); } else if line.starts_with(":derive") { return Line::Line(i, Token::Derive(String::from(line)), State::Begin); } else if line.starts_with('%') && line.ends_with('}') { return Line::LineDepth(i, Token::Module(String::from(&line[1..])), State::End, depth); } else if line.starts_with('%') { return Line::LineDepth(i, Token::Module(String::from(&line[1..])), State::Begin, depth); } else { if !line.is_empty() { return parse_struct(i, line); } } Line::Skip } fn parse_line(old: Option<&Line>, i: usize, line: &str) -> Line { // todo // lookup State::End and check line.starts_with when inside module/derive if let Some(last) = old { return match last { Line::Line(_, token, state) => { match state { State::Begin => {} State::Continue => {} State::End => { return line_starts_with(i, line, 0); } _ => {} } match token { Token::Derive(v) => parse_derive(v, i, line), _ => Line::Skip, } } Line::LineDepth(_, token, state, depth) => { match state { State::Begin => {} State::Continue => {} State::End => { return line_starts_with(i, line, 0); } _ => {} } match token { Token::Use(v) => parse_nested_use(v, i, line, *depth), Token::Module(v) => parse_nested_module(v, i, line, *depth), _ => Line::Skip } } _ => { return line_starts_with(i, line, 0); } } } else { return line_starts_with(i, line, 0); } } fn main() -> io::Result<()> { //let s = ",}},}}},}"; //.inspect //.find //let count = rcount_ends_with(s, &["}", ",}", "},"]); //println!("{:?} {}", count, s); let raw = std::fs::read("examples/components")?; let data = String::from_utf8_lossy(&raw); let default_uses = String::new(); let mut parser = tyd::parser(&parse_line); for (state, line) in parser.iter(&data) { println!("{:?}", state) } Ok(()) }