diff options
author | Mx Kookie <kookie@spacekookie.de> | 2020-12-11 17:58:39 +0000 |
---|---|---|
committer | Mx Kookie <kookie@spacekookie.de> | 2020-12-21 05:19:49 +0100 |
commit | d40e014aebc778939ae8d9afae225b7d4f6cc949 (patch) | |
tree | fa79d54a901c757149b90f8bdf329e954b432bc7 /apps/cassiopeia/src | |
parent | 717c5ccff4a03c3f459456586bcbc28cd88f6709 (diff) |
cassiopeia: adding more types to the time file abstraction
Diffstat (limited to 'apps/cassiopeia/src')
-rw-r--r-- | apps/cassiopeia/src/data.rs | 66 | ||||
-rw-r--r-- | apps/cassiopeia/src/format/mod.rs | 7 | ||||
-rw-r--r-- | apps/cassiopeia/src/format/parser.rs | 22 | ||||
-rw-r--r-- | apps/cassiopeia/src/main.rs | 3 |
4 files changed, 77 insertions, 21 deletions
diff --git a/apps/cassiopeia/src/data.rs b/apps/cassiopeia/src/data.rs index 8ebc67f016c5..3911345109ca 100644 --- a/apps/cassiopeia/src/data.rs +++ b/apps/cassiopeia/src/data.rs @@ -5,25 +5,79 @@ //! analysis tasks. use crate::format::LineCfg; -use chrono::{Date, DateTime, FixedOffset as Offset}; +use chrono::{DateTime, Duration, FixedOffset as Offset, NaiveDate}; use std::collections::BTreeMap; -#[derive(Default)] +#[derive(Debug, Default)] pub struct TimeFile { + /// Raw line buffers to echo back into the file + lines: Vec<LineCfg>, + /// A parsed header structure header: BTreeMap<String, String>, + /// A parsed session structure sessions: Vec<Session>, - invoices: Vec<Date<Offset>>, + /// A parsed invoice list + invoices: Vec<Invoice>, } impl TimeFile { - pub(crate) fn append(self, line: LineCfg) -> Self { - println!("{:?}", line); + pub(crate) fn append(mut self, line: LineCfg) -> Self { + let lo = self.lines.len(); + match line { + LineCfg::Header(ref header) => self.header = header.clone(), + LineCfg::Start(Some(time)) => self.sessions.push(Session::start(time, lo)), + LineCfg::Stop(Some(time)) => self.get_last_session().stop(time, lo), + LineCfg::Invoice(Some(date)) => self.invoices.push(Invoice::new(date, lo)), + _ => {} + } + self.lines.push(line); self } + + fn get_last_session(&mut self) -> &mut Session { + self.sessions.last_mut().unwrap() + } } +#[derive(Debug)] pub struct Session { start: DateTime<Offset>, - stop: DateTime<Offset>, + stop: Option<DateTime<Offset>>, + /// Track the lines this session took place in + lines: (usize, usize), +} + +impl Session { + /// Create a new session with a start time + fn start(start: DateTime<Offset>, line: usize) -> Self { + Self { + start, + stop: None, + lines: (line, 0), + } + } + + /// Finalise a session with a stop time + fn stop(&mut self, stop: DateTime<Offset>, line: usize) { + self.stop = Some(stop); + self.lines.1 = line; + } + + /// Get the length of the session, if it was already finished + pub fn length(&self) -> Option<Duration> { + self.stop.map(|stop| stop - self.start) + } +} + +#[derive(Debug)] +pub struct Invoice { + date: NaiveDate, + line: usize, +} + +impl Invoice { + fn new(date: NaiveDate, line: usize) -> Self { + Self { date, line } + } } diff --git a/apps/cassiopeia/src/format/mod.rs b/apps/cassiopeia/src/format/mod.rs index beab2f7aac66..bac0445d8387 100644 --- a/apps/cassiopeia/src/format/mod.rs +++ b/apps/cassiopeia/src/format/mod.rs @@ -9,7 +9,10 @@ pub(crate) use parser::LineCfg; use crate::TimeFile; use std::{fs::File, io::Read}; -pub(crate) fn load_file(path: &str) { +/// The cassiopeia parser/generator version to be written back into the file +pub const CASS_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub(crate) fn load_file(path: &str) -> TimeFile { let mut f = File::open(path).unwrap(); let mut content = String::new(); f.read_to_string(&mut content).unwrap(); @@ -21,5 +24,5 @@ pub(crate) fn load_file(path: &str) { .map(|line| lexer::lex(line)) .map(|lex| parser::parse(lex)) .filter(|line| line.valid()) - .fold(TimeFile::default(), |file, line| file.append(line)); + .fold(TimeFile::default(), |file, line| file.append(line)) } diff --git a/apps/cassiopeia/src/format/parser.rs b/apps/cassiopeia/src/format/parser.rs index cc4b1b7c77df..bb2c56be0f33 100644 --- a/apps/cassiopeia/src/format/parser.rs +++ b/apps/cassiopeia/src/format/parser.rs @@ -4,8 +4,7 @@ //! parsed time file. use crate::format::{LineLexer, LineToken, Token}; -use chrono::{DateTime, FixedOffset as Offset}; -use logos::Lexer; +use chrono::{NaiveDate, DateTime, FixedOffset as Offset}; use std::collections::BTreeMap; use std::iter::Iterator; @@ -19,9 +18,7 @@ pub enum LineCfg { /// A session stop line with a date and time Stop(Option<DateTime<Offset>>), /// An invoice line with a date - Invoice(Option<DateTime<Offset>>), - /// An empty line - Empty, + Invoice(Option<NaiveDate>), /// A temporary value that is invalid #[doc(hidden)] Ignore, @@ -39,7 +36,7 @@ impl LineCfg { pub(crate) fn parse<'l>(lex: LineLexer<'l>) -> LineCfg { use LineCfg::*; use Token as T; - + #[cfg_attr(rustfmt, rustfmt_skip)] lex.get_all().into_iter().fold(Ignore, |cfg, tok| match (cfg, tok) { // If the first token is a comment, we ignore it @@ -52,13 +49,10 @@ pub(crate) fn parse<'l>(lex: LineLexer<'l>) -> LineCfg { // If the first token _was_ a keyword, fill in the data (Header(map), LineToken { tt: T::HeaderData, slice }) => Header(append_data(map, slice)), - (Start(_), LineToken { tt: T::Date, slice }) => Start(parse_date(slice)), - (Stop(_), LineToken { tt: T::Date, slice }) => Stop(parse_date(slice)), + (Start(_), LineToken { tt: T::Date, slice }) => Start(parse_datetime(slice)), + (Stop(_), LineToken { tt: T::Date, slice }) => Stop(parse_datetime(slice)), (Invoice(_), LineToken { tt: T::Date, slice }) => Invoice(parse_date(slice)), - // Pass empty lines through, - (Empty, _) => Empty, - // Ignore everything else (which will be filtered) _ => Ignore, }) @@ -70,9 +64,13 @@ fn append_data(mut map: BTreeMap<String, String>, slice: &str) -> BTreeMap<Strin map } -fn parse_date(slice: &str) -> Option<DateTime<Offset>> { +fn parse_datetime(slice: &str) -> Option<DateTime<Offset>> { Some( DateTime::parse_from_str(slice, "%Y-%m-%d %H:%M:%S%:z") .expect("Failed to parse date; invalid format!"), ) } + +fn parse_date(slice: &str) -> Option<NaiveDate> { + Some(NaiveDate::parse_from_str(slice, "%Y-%m-%d").expect("Failed to parse date; invalid format!")) +} diff --git a/apps/cassiopeia/src/main.rs b/apps/cassiopeia/src/main.rs index b28f3c3438f7..ff942731c3d5 100644 --- a/apps/cassiopeia/src/main.rs +++ b/apps/cassiopeia/src/main.rs @@ -4,5 +4,6 @@ mod data; pub use data::{TimeFile, Session}; fn main() { - format::load_file("/home/projects/clients/nyantec-nix-workshops/time.cass") + let file = format::load_file("/home/projects/clients/nyantec-nix-workshops/time.cass"); + } |