use std::io::prelude::*; use std::io; use std::fs::File; use std::collections::BTreeMap; use chrono::prelude::*; use std::rc::Rc; use num::*; use clap::Parser; #[derive(Parser)] struct Cli { /// The path to the file to read #[clap(parse(from_os_str))] path: std::path::PathBuf} // TODO: implement any timescales greater than a second enum Timescale {ps, ns, us, ms, s} struct Scope_Idx(usize); struct Signal_Idx(usize); struct Metadata { date : DateTime, version : String, timescale : Timescale} struct Signal { name : String, timeline : BTreeMap, scope_parent : Scope_Idx} struct SignalAlias { name : String, signal_alias : Signal_Idx} enum SignalGeneric{ Signal(Signal), SignalAlias(SignalAlias)} struct Scope { name : String, child_signals : Vec, child_scopes : Vec} struct VCD { metadata : Metadata, all_signals : Vec, // the root scope should always be placed at index 0 all_scopes : Vec} #[derive(Debug)] enum Date_Parser_State {Weekday, Month, Day, HHMMSS, Year} #[derive(Debug)] enum VCD_Parser_State { Begin, Date(Date_Parser_State), Signal_Tree, Values} struct DateBuffer { Weekday : String, Month : String, Day : String, HHMMSS : String, Year : String} struct VCD_Parser<'a> { vcd_parser_state : VCD_Parser_State, date_parser_state : Date_Parser_State, date_buffer : DateBuffer, vcd : &'a VCD, curr_scope : &'a Scope, curr_parent_scope : &'a Scope} impl VCD { pub fn new() -> Self { let dt = Utc .datetime_from_str("Thu Jan 1 00:00:00 1970", "%a %b %e %T %Y") .unwrap(); let metadata = Metadata { date : dt, version : "".to_string(), timescale : Timescale::ps}; let signal = Vec::::new(); VCD { metadata : metadata, all_signals : Vec::::new(), all_scopes : Vec::::new()}}} impl<'a> VCD_Parser<'a> { pub fn new(&mut self, vcd : &'a VCD) { self.vcd_parser_state = VCD_Parser_State::Begin; self.date_parser_state = Date_Parser_State::Weekday; self.vcd = vcd;} pub fn parse_word(&mut self, word : &str) -> Result<(), String> { let mut state = &mut self.vcd_parser_state; match state { VCD_Parser_State::Begin => { match word { "$date" => {*state = VCD_Parser_State::Date(Date_Parser_State::Weekday); Ok(())}, // "$version" => {*state = VCD_Parser_State::VERSION_ENTER; Ok(())}, // "$timescale" => {*state = VCD_Parser_State::TIMESCALE_ENTER; Ok(())}, _ => Err(format!("unsure what to do with {word:?}"))}}, VCD_Parser_State::Date(Date_Parser_State) => { let res = self.parse_date(word); Ok(()) } _ => Err(format!("parser in bad state : {state:?}"))} } pub fn parse_date(&mut self, word : &str) -> Result<(), String> { let mut state = &mut self.date_parser_state; Ok(()) } } fn advance_VCD_parser_FSM(word: &str, mut state : VCD_Parser_State) {} fn advance_Date_parser_FSM(word : &str, mut state : Date_Parser_State) {} fn yield_word_and_apply(file : File, mut f : impl FnMut(&str)) { let mut reader = io::BufReader::new(file); let mut buffer = String::new(); let mut word_count = 0u64; let mut EOF = false; let line_chunk_size = 25; while {!EOF} { for _ in 0..line_chunk_size { let bytes_read = reader.read_line(&mut buffer).unwrap(); if bytes_read == 0 { EOF = true; break } } let words = buffer.split_ascii_whitespace(); for word in words { f(word); } buffer.clear(); } } fn main() -> std::io::Result<()> { let args = Cli::parse(); // let dt = Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"); let file = File::open(&args.path)?; let mut word_count = 0; yield_word_and_apply(file, |word| {word_count += 1}); dbg!(word_count); Ok(()) }