Verified Commit 7818e0da authored by Maxime Buquet's avatar Maxime Buquet
Browse files

impl wrapper type Days



If you know how to do this better please help.

The Day type needs to be serialized into a map, with stringified dates
as keys, and stringified items as values. Day is just a special case of
Vec<Day>, that is, a Vec of only one Day.

I cannot `impl Serializer for Vec<Day>` because these types are not
declared in the crate. So I implemented Days, that wraps a vec, but
users will have to use this instead and that's meh.
Signed-off-by: Maxime Buquet's avatarMaxime “pep” Buquet <pep@bouah.net>
parent 7cd3a9c6
......@@ -58,6 +58,11 @@ dependencies = [
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dtoa"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "env_logger"
version = "0.5.13"
......@@ -78,6 +83,21 @@ dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.1.0"
......@@ -99,6 +119,11 @@ dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.1.0"
......@@ -122,6 +147,11 @@ name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quick-error"
version = "1.2.2"
......@@ -160,6 +190,22 @@ dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_urlencoded"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.7.0"
......@@ -217,6 +263,8 @@ dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"try_from 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -230,11 +278,34 @@ name = "ucd-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "utf8-ranges"
version = "1.0.1"
......@@ -294,19 +365,26 @@ dependencies = [
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341"
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
"checksum serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aaed41d9fb1e2f587201b863356590c90c1157495d811430a0c0325fe8169650"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
......@@ -315,7 +393,10 @@ dependencies = [
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
"checksum try_from 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "923a7ee3e97dbfe8685261beb4511cc9620a1252405d02693d43169729570111"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
......
......@@ -10,3 +10,5 @@ log = "0.4.3"
env_logger = "0.5.10"
chrono = "0.4.4"
try_from = "0.2.2"
serde = "1.0.79"
serde_urlencoded = "0.5.3"
......@@ -6,8 +6,8 @@
extern crate chrono;
extern crate serde;
extern crate try_from;
extern crate serde_urlencoded;
extern crate try_from;
pub mod errors;
pub mod types;
......@@ -114,12 +114,10 @@ pub fn duration_to_string(d: &Duration) -> String {
impl<'a> From<&'a Entry> for String {
fn from(e: &Entry) -> String {
let d = duration_to_string(&e.duration);
match &e.comment {
None => format!("{}: {}:", &e.duration, &e.task),
Some(ref c) => {
let d = duration_to_string(&e.duration);
format!("{} {}: {}", d, &e.task, c)
}
None => format!("{}: {}:", d, &e.task),
Some(ref c) => format!("{} {}: {}", d, &e.task, c),
}
}
}
......@@ -170,19 +168,60 @@ pub struct Day {
items: Vec<Entry>,
}
impl Serialize for Day {
impl Day {
pub fn new(date: Date<Utc>, items: Vec<Entry>) -> Day {
Day {
date,
items,
}
}
}
// TODO: This is a really poor attempt at being able to Serialize Day and
// Vec<Day> the same way. There must be a better way. Halp.
#[derive(Debug, Clone, PartialEq)]
pub struct Days (Vec<Day>);
impl Days {
pub fn new(days: Vec<Day>) -> Days {
Days (days)
}
}
impl From<Day> for Days {
fn from(day: Day) -> Days {
Days(vec![day])
}
}
impl From<Vec<Day>> for Days {
fn from(vec: Vec<Day>) -> Days {
Days(vec)
}
}
impl Into<Vec<Day>> for Days {
fn into(self: Days) -> Vec<Day> {
self.0
}
}
impl Serialize for Days {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(self.items.len()))?;
let s_date = self.date.format("%Y-%m-%d").to_string();
let s_items = self.items.iter().fold(String::new(), |mut s, item| {
s.push_str(String::from(item).as_str());
s.push_str("\n");
s
});
map.serialize_entry(&s_date, &s_items)?;
let mut map = serializer.serialize_map(Some(self.0.len()))?;
self.0.iter().try_for_each(|day| -> Result<(), S::Error> {
let s_date = day.date.format("%Y-%m-%d").to_string();
let s_items = day.items.iter().fold(String::new(), |mut s, item| {
s.push_str(String::from(item).as_str());
s.push_str("\n");
s
});
map.serialize_entry(&s_date, &s_items)?;
Ok(())
})?;
map.end()
}
}
......@@ -220,7 +259,7 @@ impl TryFrom<TimesheetDay> for Day {
#[cfg(test)]
mod test {
use super::{Day, Entry, Task};
use super::{Day, Days, Entry, Task};
use chrono::{Date, Duration, NaiveDate, Utc};
use errors::ChronophageError as Error;
use serde_urlencoded;
......@@ -301,25 +340,68 @@ mod test {
#[test]
fn serialize_day() {
let day = Day {
date: Date::from_utc(NaiveDate::from_ymd(2018, 7, 5), Utc),
items: vec![
Entry::new(
Duration::minutes(5),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
Entry::new(
Duration::hours(7),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
],
};
let days = Days::from(
Day::new(
Date::from_utc(NaiveDate::from_ymd(2018, 7, 5), Utc),
vec![
Entry::new(
Duration::minutes(5),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
Entry::new(
Duration::hours(7),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
],
)
);
let result = "2018-07-05=0%3A05+foo%3A+bar%3A+baz%3A+qxx%3A+Test%0A7%3A00+foo%3A+bar%3A+baz%3A+qxx%3A+Test%0A";
assert_eq!(serde_urlencoded::to_string(day), Ok(String::from(result)));
assert_eq!(serde_urlencoded::to_string(days), Ok(String::from(result)));
}
#[test]
fn serialize_days() {
let days = Days::new(vec![
Day::new(
Date::from_utc(NaiveDate::from_ymd(2018, 7, 5), Utc),
vec![
Entry::new(
Duration::minutes(5),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
Entry::new(
Duration::hours(7),
Task::new("foo", "bar", "baz", "qxx"),
None::<String>,
),
],
),
Day::new(
Date::from_utc(NaiveDate::from_ymd(2018, 7, 6), Utc),
vec![
Entry::new(
Duration::hours(2) + Duration::minutes(53),
Task::new("foo", "bar", "baz", "qxx"),
None::<String>,
),
Entry::new(
Duration::hours(7),
Task::new("foo", "bar", "baz", "qxx"),
Some("Test"),
),
],
),
]);
let result = "2018-07-05=0%3A05+foo%3A+bar%3A+baz%3A+qxx%3A+Test%0A7%3A00%3A+foo%3A+bar%3A+baz%3A+qxx%3A%0A\
&2018-07-06=2%3A53%3A+foo%3A+bar%3A+baz%3A+qxx%3A%0A7%3A00+foo%3A+bar%3A+baz%3A+qxx%3A+Test%0A";
assert_eq!(serde_urlencoded::to_string(days), Ok(String::from(result)));
}
#[test]
......
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