Verified Commit dcfc28ed authored by Maxime Buquet's avatar Maxime Buquet
Browse files

Timesheet::try_from(day) WIP


Signed-off-by: Maxime Buquet's avatarMaxime “pep” Buquet <pep@bouah.net>
parent aa824762
......@@ -11,6 +11,7 @@ env_logger = "0.5.10"
chrono = "0.4"
lazy_static = "1.0"
regex = "0.2"
try_from = "0.2.2"
[dependencies.nom]
version = "4.0"
......
......@@ -9,6 +9,7 @@ use std::io;
#[derive(Debug)]
pub enum Error {
ParseError,
NotEnoughEntries,
IOError(io::Error),
}
......
......@@ -10,6 +10,7 @@ extern crate regex;
#[macro_use]
extern crate lazy_static;
extern crate chrono;
extern crate try_from;
pub mod types;
pub mod errors;
......
......@@ -5,6 +5,7 @@
//
use try_from::TryFrom;
use errors::Error;
use chrono::{DateTime, Date, Utc, Duration};
......@@ -111,9 +112,55 @@ pub struct Timesheet {
pub items: Vec<TimesheetItem>,
}
impl TryFrom<Day> for Timesheet {
type Err = Error;
fn try_from(day: Day) -> Result<Timesheet, Error> {
let items = day.entries.into_iter().fold((vec![], None), |(mut acc, last_entry), entry| {
if last_entry.is_none() || entry.is_dummy() {
return (acc, Some(entry));
}
match last_entry {
Some(last_entry) => {
match &entry.entry {
EntryType::Full(entry_foo) => {
let item = TimesheetItem::new(
entry.datetime - last_entry.datetime,
&entry_foo.project,
&entry_foo.category,
&entry_foo.activity,
&entry_foo.task,
&entry_foo.comment,
);
acc.push(item);
return (acc, Some(entry.clone()))
},
_ => unreachable!(),
}
},
_ => unreachable!(),
}
}).0;
if items.len() == 0 {
return Err(Error::NotEnoughEntries);
}
Ok(Timesheet {
date: day.date,
items,
})
}
}
#[cfg(test)]
mod test {
use super::Entry;
use try_from::TryFrom;
use chrono::{Date, NaiveDate, Utc, TimeZone, Duration};
use super::{TimesheetItem, Timesheet, Day, Entry};
use errors::Error;
#[test]
fn test_entry_is_full() {
......@@ -152,4 +199,91 @@ mod test {
assert!(!entry_full.is_dummy());
assert!(entry_dummy.is_dummy());
}
#[test]
fn test_timesheet_from_day_empty() {
let day = Day {
date: Date::from_utc(NaiveDate::from_ymd(2018, 7, 3), Utc),
entries: vec![],
};
match Timesheet::try_from(day) {
Err(Error::NotEnoughEntries) => (),
_ => panic!(),
}
}
#[test]
fn test_timesheet_from_day_one_entry() {
let day = Day {
date: Date::from_utc(NaiveDate::from_ymd(2018, 7, 3), Utc),
entries: vec![
Entry::new_dummy(
Utc.ymd(2018, 7, 3).and_hms(10, 0, 0),
"dummy1 **",
),
],
};
match Timesheet::try_from(day) {
Err(Error::NotEnoughEntries) => (),
_ => panic!(),
}
}
#[test]
fn test_timesheet_from_day() {
let day = Day {
date: Date::from_utc(NaiveDate::from_ymd(2018, 7, 3), Utc),
entries: vec![
Entry::new_dummy(
Utc.ymd(2018, 7, 3).and_hms(10, 0, 0),
"dummy1 **",
),
Entry::new_full(
Utc.ymd(2018, 7, 3).and_hms(10, 15, 0),
"project1",
"category1",
"activity1",
"task1",
"comment1",
),
Entry::new_full(
Utc.ymd(2018, 7, 3).and_hms(18, 0, 0),
"project2",
"category2",
"activity2",
"task2",
"comment2",
),
],
};
let result = Timesheet {
date: Date::from_utc(NaiveDate::from_ymd(2018, 7, 3), Utc),
items: vec![
TimesheetItem::new(
Duration::minutes(15),
"project1",
"category1",
"activity1",
"task1",
"comment1",
),
TimesheetItem::new(
Duration::hours(7) + Duration::minutes(45),
"project2",
"category2",
"activity2",
"task2",
"comment2",
),
],
};
match Timesheet::try_from(day) {
Ok(timesheet) => assert_eq!(timesheet, result),
Err(err) => { println!("Err: {:?}", err); panic!(err) },
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment