use std::path::{PathBuf,Path}; use std::collections::HashMap; use core::error::Error; use std::time::SystemTime; mod lexer; mod parser; #[derive(Debug,Copy,Clone)] pub struct Position { pub line: u32, pub column: u32, } impl Position { pub fn new( line: u32, column: u32 ) -> Self { Self { line, column, } } } pub struct Crimtag { fragments: HashMap, sources: Vec, } #[derive(PartialEq,Eq,Debug,Clone)] enum FragmentSource { File { path: PathBuf, loaded: SystemTime, }, Static, External { key: String, }, } struct Fragment { name: String, source: usize, sections: HashMap, } struct Section { name: String, ast_root: Token, } type Properties = HashMap; enum Token { Root(Vec), Fragment(String,Properties,Vec), Section(String,Properties,Vec), Text(String), Literal(String), /* Tag{ name: String, params: Vec, props: Properties, children: Vec },*/ } struct State { } impl Crimtag { pub fn new() -> Self { Self { fragments: HashMap::new(), sources: vec![FragmentSource::Static], } } fn id_source(&mut self, src: &FragmentSource ) -> usize { for idx in 0..self.sources.len() { if self.sources[idx] == *src { return idx; } } // Nothing found, add a new one let idx = self.sources.len(); self.sources.push( src.clone() ); idx } pub fn load_file(&mut self, path: &Path) -> Result<(),Box::> { let time = if let Ok(meta) = path.metadata() { if let Ok(t) = meta.modified() { t } else if let Ok(t) = meta.created() { t } else { SystemTime::now() } } else { SystemTime::now() }; let mut p = parser::Parser::new(); p.parse( &String::from_utf8( std::fs::read( path )? )? ); Ok(()) } pub fn load_static(&mut self, data: &str) -> Result<(),Box::> { let mut p = parser::Parser::new(); p.parse( &data ); Ok(()) } pub fn load_external(&mut self, key: &str, data: &str) -> Result<(),Box::> { Ok(()) } } #[cfg(test)] mod tests { use super::*; use crate::lexer::*; #[test] fn lexing() { let data = r#"Leading comment: [|fragment "basic" something="yeup"|>Hello there <|fragment|] Trailing text"#; let ll = lexer::Lexer::new( &data ); for sym in ll { if let SymbolType::Error{what} = sym.symbol() { println!("Error {}:{}: {:?}", sym.start().line, sym.start().column, what ); break; } else { println!("Symbol: {:?}", sym ); } } } #[test] fn parsing() { let mut ct = Crimtag::new(); if let Err(e) = ct.load_static(r#"Here is a sample [|fragment "index" theme="standard"|>Hi<|fragment|] That was fun!"#) { println!("Error: {:?}", e ); } else { println!("It finished"); } } }