diff --git a/Cargo.toml b/Cargo.toml index 494728b..321546a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,7 @@ edition = "2021" [dependencies] num = "0.4" clap = { version = "3.1.8", features = ["derive"] } +chrono = "0.4" +nom = "7.1.1" +genawaiter = "0.99.1" +nom-bufreader = "0.2.0" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5423c94..8711738 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,25 @@ use std::io::prelude::*; use std::io; use std::fs::File; +use genawaiter::{sync::gen, yield_}; use num::*; use clap::Parser; +use chrono::prelude::*; +use std::collections::BTreeMap; + +use nom_bufreader::bufreader::BufReader; +use nom_bufreader::{Error, Parse}; +use nom::{ + branch::alt, + bytes::streaming::{tag, take_until, take_while1}, + character::streaming::{space0,alpha1, multispace1, digit1}, + combinator::map_res, + IResult, + sequence::tuple +}; + +// TODO : Remove +use std::str::from_utf8; #[derive(Parser)] struct Cli { @@ -17,44 +34,139 @@ struct Timestamp{ timestamp: BigInt } +// TODO: implement any timescales greater than a second +#[derive(Debug)] +enum Timescale {ps, ns, us, ms, s, unit} + +#[derive(Debug)] +struct Scope_Idx(usize); + +#[derive(Debug)] +struct Signal_Idx(usize); + +#[derive(Debug)] +struct Version(String); + +#[derive(Debug)] +struct Metadata { + date : Option>, + version : Option, + timescale : (Option, Timescale)} + +#[derive(Debug)] +enum SignalGeneric{ + Signal{ + name : String, + timeline : BTreeMap, + scope_parent : Scope_Idx}, + SignalAlias{ + name : String, + signal_alias : Signal_Idx} +} + +#[derive(Debug)] +struct Scope { + name : String, + child_signals : Vec, + child_scopes : Vec} + + +#[derive(Debug)] +struct VCD { + metadata : Metadata, + all_signals : Vec, + // the root scope should always be placed at index 0 + all_scopes : Vec} + +fn method(i: &[u8]) -> IResult<&[u8], String, ()> { + map_res(alt((tag("GET"), tag("POST"), tag("HEAD"))), |s| { + from_utf8(s).map(|s| s.to_string()) + })(i) +} + +fn path(i: &[u8]) -> IResult<&[u8], String, ()> { + map_res(take_until(" "), |s| from_utf8(s).map(|s| s.to_string()))(i) +} + +fn date(i: &[u8]) -> IResult<&[u8], DateTime, ()> { + let (i, _) = tag("$date")(i)?; + + let (i, _) = multispace1(i)?; + let (i, weekday) = alt(( + tag("Mon"), tag("Tue"), tag("Wed"), tag("Thu"), + tag("Fri"), tag("Sat"), tag("Sun")))(i)?; + + let (i, _) = multispace1(i)?; + let (i, month) = alt(( + tag("Jan"), tag("Feb"), tag("Mar"), tag("Apr"), + tag("May"), tag("Jun"), tag("July"), tag("Sept"), + tag("Oct"), tag("Nov"), tag("Dec")))(i)?; + + let (i, _) = multispace1(i)?; + let (i, day) = digit1(i)?; + + let (i, _) = multispace1(i)?; + let (i, hour) = digit1(i)?; + + let (i, _) = tag(":")(i)?; + let (i, minute) = digit1(i)?; + + let (i, _) = tag(":")(i)?; + let (i, second) = digit1(i)?; + + let (i, _) = multispace1(i)?; + let (i, year) = digit1(i)?; + + let (i, _) = multispace1(i)?; + let (i, _) = tag("$end")(i)?; + + let (weekday, month, day, hour, minute, second, year) = ( + from_utf8(weekday).unwrap(), + from_utf8(month).unwrap(), + from_utf8(day).unwrap(), + from_utf8(hour).unwrap(), + from_utf8(minute).unwrap(), + from_utf8(second).unwrap(), + from_utf8(year).unwrap(), + ); + + let dt = Utc.datetime_from_str( + format!("{weekday} {month} {day} {hour}:{minute}:{second} {year}") + .as_str(), "%a %b %e %T %Y") + .unwrap(); + + Ok((i, dt)) + +} + +fn space(i: &[u8]) -> IResult<&[u8], (), ()> { + let (i, _) = space0(i)?; + Ok((i, ())) +} + fn main() -> std::io::Result<()> { let args = Cli::parse(); let file = File::open(&args.path)?; - let mut reader = io::BufReader::new(file); + let mut reader = BufReader::new(file); + let m = reader.parse(date).expect("failed to parse date"); + dbg!(m.to_rfc2822()); - let mut buffer = String::new(); - let mut timestamp_offsets = Vec::new(); - let mut timestamps = Vec::new(); + // let mut file_by_line = gen!({ + // while { + // let bytes_read = reader.read_line(&mut buffer).unwrap(); + // bytes_read > 0 + // } { + // yield_!(buffer.as_bytes()); + // buffer.clear() + // } + // }); - while { - let bytes_read = reader.read_line(&mut buffer).unwrap(); - bytes_read > 0 - } { - if &buffer[0..1] == "#" { - let pos = reader.stream_position().unwrap(); - timestamp_offsets.push(pos); + // for line in file_by_line { + // dbg!(&line); + // } - let timestamp = { - let len = buffer.len(); - let str_val = &buffer[1..(len - 1)].as_bytes(); - BigInt::parse_bytes(str_val, 10).unwrap() - }; - timestamps.push(timestamp); - } - buffer.clear() - } - let index = 4; - let timestamp_offset = timestamp_offsets.get(index).unwrap(); - let timestamp = timestamps.get(index).unwrap(); - dbg!((timestamp_offset, timestamp)); - - // seek to where we found the first timestamp and read - // out the next line - reader.seek(io::SeekFrom::Start(*timestamp_offset)); - reader.read_line(&mut buffer); - dbg!(buffer); Ok(()) }