#[cfg(engine)]
mod engine {
use super::InvalidDuration;
use chrono::Utc;
use std::time;
#[derive(Debug, Clone)]
pub struct ComputedDuration(chrono::Duration);
impl ComputedDuration {
pub fn compute_timestamp(&self) -> String {
let current = Utc::now();
let datetime = current + self.0;
datetime.to_rfc3339()
}
}
pub trait PerseusDuration {
fn into_computed(self) -> Result<ComputedDuration, InvalidDuration>;
}
impl PerseusDuration for chrono::Duration {
fn into_computed(self) -> Result<ComputedDuration, InvalidDuration> {
Ok(ComputedDuration(self))
}
}
impl PerseusDuration for &str {
fn into_computed(self) -> Result<ComputedDuration, InvalidDuration> {
let mut duration = chrono::Duration::zero();
let mut curr_duration_length = String::new();
for c in self.chars() {
if c.is_numeric() {
curr_duration_length.push(c);
} else {
let interval_length: i64 = curr_duration_length.parse().unwrap(); if interval_length <= 0 {
return Err(InvalidDuration);
}
match c {
's' => duration = duration + chrono::Duration::seconds(interval_length),
'm' => duration = duration + chrono::Duration::minutes(interval_length),
'h' => duration = duration + chrono::Duration::hours(interval_length),
'd' => duration = duration + chrono::Duration::days(interval_length),
'w' => duration = duration + chrono::Duration::weeks(interval_length),
'M' => duration = duration + chrono::Duration::days(interval_length * 30),
'y' => duration = duration + chrono::Duration::days(interval_length * 365),
_ => return Err(InvalidDuration),
};
curr_duration_length = String::new();
}
}
Ok(ComputedDuration(duration))
}
}
impl PerseusDuration for time::Duration {
fn into_computed(self) -> Result<ComputedDuration, InvalidDuration> {
let duration = chrono::Duration::from_std(self).map_err(|_| InvalidDuration)?;
Ok(ComputedDuration(duration))
}
}
}
#[cfg(client)]
mod browser {
use super::InvalidDuration;
use std::time;
#[derive(Debug, Clone)]
pub struct ComputedDuration;
pub trait PerseusDuration {
fn into_computed(self) -> Result<ComputedDuration, InvalidDuration>
where
Self: Sized,
{
unreachable!("computed durations can only be created on the engine-side")
}
}
impl PerseusDuration for &str {}
impl PerseusDuration for time::Duration {}
}
#[derive(Debug)]
pub struct InvalidDuration;
#[cfg(client)]
pub use browser::{ComputedDuration, PerseusDuration};
#[cfg(engine)]
pub use engine::{ComputedDuration, PerseusDuration};