aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--dome_key_map.h2
-rw-r--r--src/errors.rs10
-rw-r--r--src/lib.rs5
-rw-r--r--src/trial.rs86
5 files changed, 104 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e66a57a..c5bee52 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ getopts = "0.2.18"
libc = "0.2.43"
log = "0.4.5"
objc = "0.2.5"
+quick-error = "1.2.2"
serde = "1.0.58"
serde_derive = "1.0.58"
stderrlog = "0.4.1"
diff --git a/dome_key_map.h b/dome_key_map.h
index a6e44ca..88909f0 100644
--- a/dome_key_map.h
+++ b/dome_key_map.h
@@ -6,6 +6,8 @@
#include <stdlib.h>
#include <stdbool.h>
+#define DAYS_REMAINING 30
+
typedef enum {
HeadphoneButton_Play,
HeadphoneButton_Up,
diff --git a/src/errors.rs b/src/errors.rs
index beafc9f..5f09c27 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -5,3 +5,13 @@ error_chain! {
Xdg(xdg::BaseDirectoriesError);
}
}
+
+quick_error! {
+ #[derive(Debug, PartialEq)]
+ pub enum DurationError {
+ NegativeDuration(duration: i32) {
+ description("negative duration")
+ display("negative duration: '{}'", duration)
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 801591c..8e23367 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
#![recursion_limit="128"]
extern crate autopilot;
+extern crate chrono;
extern crate cocoa;
#[macro_use]
@@ -20,6 +21,9 @@ extern crate log;
extern crate objc;
#[macro_use]
+extern crate quick_error;
+
+#[macro_use]
extern crate serde_derive;
extern crate stderrlog;
extern crate toml;
@@ -31,6 +35,7 @@ mod config;
mod errors;
mod key_code;
mod parser;
+mod trial;
use parser::{Action, HeadphoneButton, MapAction, MapGroup, MapKind};
diff --git a/src/trial.rs b/src/trial.rs
new file mode 100644
index 0000000..9604f62
--- /dev/null
+++ b/src/trial.rs
@@ -0,0 +1,86 @@
+use chrono::{DateTime, Local, TimeZone};
+
+use errors::DurationError;
+
+// Start timestamp on October 1 at 23h
+// Trial should be valid until November 1 00h
+
+
+const DAYS_REMAINING: u8 = 30;
+
+fn days_remaining(
+ start: DateTime<Local>,
+ now: DateTime<Local>,
+ days_available: u8,
+) -> Result<u8, DurationError> {
+ let duration = (now.date() - start.date()).num_days() as u8;
+
+ if duration > days_available {
+ Err(
+ DurationError::NegativeDuration(days_available as i32 - duration as i32)
+ )
+ } else {
+ Ok(days_available - duration)
+ }
+}
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn days_remaining_counts_days_remaining_from_start_date() {
+ let remaining = days_remaining(
+ Local.ymd(2018, 10, 1).and_hms(23, 1, 0),
+ Local.ymd(2018, 10, 1).and_hms(23, 30, 0),
+ 30,
+ );
+
+ assert_eq!(remaining, Ok(30));
+ }
+
+ #[test]
+ fn days_remaining_with_middle_date() {
+ let remaining = days_remaining(
+ Local.ymd(2018, 10, 1).and_hms(23, 1, 0),
+ Local.ymd(2018, 10, 22).and_hms(15, 0, 0),
+ 30,
+ );
+
+ assert_eq!(remaining, Ok(9));
+ }
+
+ #[test]
+ fn days_remaining_on_last_day_is_0() {
+ let remaining = days_remaining(
+ Local.ymd(2018, 10, 1).and_hms(23, 1, 0),
+ Local.ymd(2018, 10, 31).and_hms(23, 30, 0),
+ 30,
+ );
+
+ assert_eq!(remaining, Ok(0));
+ }
+
+ #[test]
+ fn days_remaining_on_day_following_last_day_is_negative_duration_error() {
+ let remaining = days_remaining(
+ Local.ymd(2018, 10, 1).and_hms(23, 1, 0),
+ Local.ymd(2018, 11, 1).and_hms(0, 0, 0),
+ 30,
+ );
+
+ assert_eq!(remaining, Err(DurationError::NegativeDuration(-1)));
+ }
+
+ #[test]
+ fn days_remaining_after_last_day_is_negative_duration_error() {
+ let remaining = days_remaining(
+ Local.ymd(2018, 10, 1).and_hms(23, 1, 0),
+ Local.ymd(2018, 11, 5).and_hms(0, 0, 0),
+ 30,
+ );
+
+ assert_eq!(remaining, Err(DurationError::NegativeDuration(-5)));
+ }
+}