From 1cee3956d224f869bc55827b30459b237ae14d45 Mon Sep 17 00:00:00 2001 From: Jonathan Strong Date: Thu, 26 Mar 2020 03:32:12 -0400 Subject: [PATCH] begin adding case study --- Cargo.toml | 2 + src/case_study.rs | 137 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 37 +++++++------ 3 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 src/case_study.rs diff --git a/Cargo.toml b/Cargo.toml index 6c68a51..1b07623 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +chrono = "0.4" +uuid = { version = "0.7", features = ["v4"] } diff --git a/src/case_study.rs b/src/case_study.rs new file mode 100644 index 0000000..6724a84 --- /dev/null +++ b/src/case_study.rs @@ -0,0 +1,137 @@ +use std::net::Ipv4Addr; +use chrono::{DateTime, Utc}; +use uuid::Uuid; + +pub struct Event { + pub time: DateTime, + pub id: Uuid, + pub event: T, +} + +pub struct Pending{ + pub recipient: Ipv4Addr, +} + +pub struct Sending { + pub payload: Vec, + pub bytes_sent: usize, + pub prev: Event, +} + +pub struct Sent { + pub ack_req: bool, + pub prev: Event, +} + +pub struct Ack { + pub data: Vec, + pub prev: Event, +} + +pub struct Finished { + pub prev: Event, +} + +pub enum Active { + Pending(Event), + Sending(Event), + Sent(Event), + Acked(Event), + FinishedNoAck(Event>), + FinishedAcked(Event>), +} + +pub trait Timestamped { + fn time(&self) -> DateTime; +} + +pub trait Chronological { + type Prev; + type Next; + + fn prev(&self) -> Self::Prev; + fn next(&self) -> Self::Next; +} + +pub trait Elapsed: Chronological { + fn elapsed(&self) -> chrono::Duration; +} + +impl Timestamped for Event { + fn time(&self) -> DateTime { self.time } +} + +impl Elapsed for T + where T: Chronological, + P: Timestamped, + N: Timestamped +{ + fn elapsed(&self) -> chrono::Duration { + self.next().time().signed_duration_since(self.prev().time()) + } +} + +impl Elapsed<(), N> for T + where T: Chronological +{ + fn elapsed(&self) -> chrono::Duration { + chrono::Duration::seconds(0) + } +} + +impl Timestamped for Active { + fn time(&self) -> DateTime { + use Active::*; + match self { + Pending(event) => event.time, + Sending(event) => event.time, + Sent(event) => event.time, + Acked(event) => event.time, + FinishedNoAck(event) => event.time, + FinishedAcked(event) => event.time, + } + } +} + +macro_rules! event_attr { + ($method:ident, $t:ident, $attr:ident) => { + fn $method(&self) -> $t { + use Active::*; + match self { + Pending(event) => event.$attr, + Sending(event) => event.$attr, + Sent(event) => event.$attr, + Acked(event) => event.$attr, + FinishedNoAck(event) => event.$attr, + FinishedAcked(event) => event.$attr, + } + } + } +} + +impl Active { + event_attr!(id, Uuid, id); +} + +#[allow(unused)] +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn event_attr_accessors_work() { + let pending = Pending { recipient: "0.0.0.0".parse().unwrap() }; + let now = Utc::now(); + let id = Uuid::new_v4(); + let pending_event = Event { + time: now, + id, + event: pending, + }; + let pending_active = Active::Pending(pending_event); + assert_eq!(pending_active.time(), now); + assert_eq!(pending_active.id(), id); + } +} + diff --git a/src/lib.rs b/src/lib.rs index 67edbac..e3db6e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,12 @@ //! } //! make_adder_fn!(42); //! ``` +//! + +pub mod case_study; + +#[allow(unused)] #[cfg(test)] mod tests { @@ -319,26 +324,26 @@ mod tests { ::abc(&$x) } } - let c = ::abc(&a); + //let c = ::abc(&a); - macro_rules! you_gotta_be_wiser { - { [[ $x:ident ]] } => { - ::abc(&$x) - } - //{ [[ $x:ident ]] } => { - // ::abc(&$x) - //}; - - //{ -^-^- $x:ident -^-^- } => {{ - // // invoking the version that's inside `the_upside_down` - // use crate::tests::example_for_why_you_should_use_fully_qualified_names::the_upside_down::Devious as OtherDevious; - // ::xyz(&$x) - //}}; - } + //macro_rules! you_gotta_be_wiser { + // { [[ $x:ident ]] } => { + // ::abc(&$x) + // } + // //{ [[ $x:ident ]] } => { + // // ::abc(&$x) + // //}; + + // //{ -^-^- $x:ident -^-^- } => {{ + // // // invoking the version that's inside `the_upside_down` + // // use crate::tests::example_for_why_you_should_use_fully_qualified_names::the_upside_down::Devious as OtherDevious; + // // ::xyz(&$x) + // //}}; + //} assert_eq!(didnt_see_it_coming!{ a <-> }, 42); - assert_eq!(you_gotta_be_wiser!{ [[ a ]] }, 42); + //assert_eq!(you_gotta_be_wiser!{ [[ a ]] }, 42); //assert_eq!(you_gotta_be_wiser!{ -^-^- a -^-^- }, -42); /// muhaha