@@ -7,3 +7,5 @@ edition = "2018" | |||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||
[dependencies] | [dependencies] | ||||
chrono = "0.4" | |||||
uuid = { version = "0.7", features = ["v4"] } |
@@ -0,0 +1,137 @@ | |||||
use std::net::Ipv4Addr; | |||||
use chrono::{DateTime, Utc}; | |||||
use uuid::Uuid; | |||||
pub struct Event<T> { | |||||
pub time: DateTime<Utc>, | |||||
pub id: Uuid, | |||||
pub event: T, | |||||
} | |||||
pub struct Pending{ | |||||
pub recipient: Ipv4Addr, | |||||
} | |||||
pub struct Sending { | |||||
pub payload: Vec<u8>, | |||||
pub bytes_sent: usize, | |||||
pub prev: Event<Ipv4Addr>, | |||||
} | |||||
pub struct Sent { | |||||
pub ack_req: bool, | |||||
pub prev: Event<Sending>, | |||||
} | |||||
pub struct Ack { | |||||
pub data: Vec<u8>, | |||||
pub prev: Event<Sent>, | |||||
} | |||||
pub struct Finished<T> { | |||||
pub prev: Event<T>, | |||||
} | |||||
pub enum Active { | |||||
Pending(Event<Pending>), | |||||
Sending(Event<Sending>), | |||||
Sent(Event<Sent>), | |||||
Acked(Event<Ack>), | |||||
FinishedNoAck(Event<Finished<Sent>>), | |||||
FinishedAcked(Event<Finished<Ack>>), | |||||
} | |||||
pub trait Timestamped { | |||||
fn time(&self) -> DateTime<Utc>; | |||||
} | |||||
pub trait Chronological { | |||||
type Prev; | |||||
type Next; | |||||
fn prev(&self) -> Self::Prev; | |||||
fn next(&self) -> Self::Next; | |||||
} | |||||
pub trait Elapsed<P, N>: Chronological<Prev = P, Next = N> { | |||||
fn elapsed(&self) -> chrono::Duration; | |||||
} | |||||
impl<T> Timestamped for Event<T> { | |||||
fn time(&self) -> DateTime<Utc> { self.time } | |||||
} | |||||
impl<P, N, T> Elapsed<P, N> for T | |||||
where T: Chronological<Prev = P, Next = N>, | |||||
P: Timestamped, | |||||
N: Timestamped | |||||
{ | |||||
fn elapsed(&self) -> chrono::Duration { | |||||
self.next().time().signed_duration_since(self.prev().time()) | |||||
} | |||||
} | |||||
impl<N, T> Elapsed<(), N> for T | |||||
where T: Chronological<Prev = (), Next = N> | |||||
{ | |||||
fn elapsed(&self) -> chrono::Duration { | |||||
chrono::Duration::seconds(0) | |||||
} | |||||
} | |||||
impl Timestamped for Active { | |||||
fn time(&self) -> DateTime<Utc> { | |||||
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); | |||||
} | |||||
} | |||||
@@ -44,7 +44,12 @@ | |||||
//! } | //! } | ||||
//! make_adder_fn!(42); | //! make_adder_fn!(42); | ||||
//! ``` | //! ``` | ||||
//! | |||||
pub mod case_study; | |||||
#[allow(unused)] | |||||
#[cfg(test)] | #[cfg(test)] | ||||
mod tests { | mod tests { | ||||
@@ -319,26 +324,26 @@ mod tests { | |||||
<A as Devious>::abc(&$x) | <A as Devious>::abc(&$x) | ||||
} | } | ||||
} | } | ||||
let c = <A as ::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::abc(&a); | |||||
//let c = <A as ::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::abc(&a); | |||||
macro_rules! you_gotta_be_wiser { | |||||
{ [[ $x:ident ]] } => { | |||||
<A as ::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::abc(&$x) | |||||
} | |||||
//{ [[ $x:ident ]] } => { | |||||
// <A as crate::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::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; | |||||
// <A as crate::tests::example_for_why_you_should_use_fully_qualified_names::the_upside_down::OtherDevious>::xyz(&$x) | |||||
//}}; | |||||
} | |||||
//macro_rules! you_gotta_be_wiser { | |||||
// { [[ $x:ident ]] } => { | |||||
// <A as ::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::abc(&$x) | |||||
// } | |||||
// //{ [[ $x:ident ]] } => { | |||||
// // <A as crate::tests::example_for_why_you_should_use_fully_qualified_names::Devious>::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; | |||||
// // <A as crate::tests::example_for_why_you_should_use_fully_qualified_names::the_upside_down::OtherDevious>::xyz(&$x) | |||||
// //}}; | |||||
//} | |||||
assert_eq!(didnt_see_it_coming!{ a <-> }, 42); | 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); | //assert_eq!(you_gotta_be_wiser!{ -^-^- a -^-^- }, -42); | ||||
/// muhaha | /// muhaha | ||||