sacs 0.9.4

Simple Async Cron Scheduler for Tokio
Documentation
use crate::task::TaskId;
use chrono::{DateTime, Local};
use std::fmt::Debug;
use std::time::SystemTime;
use uuid::Uuid;

#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub(crate) struct EventId {
    pub id: String,
}

impl Default for EventId {
    fn default() -> Self {
        Self {
            id: Uuid::new_v4().into(),
        }
    }
}

impl From<Uuid> for EventId {
    fn from(value: Uuid) -> Self {
        Self { id: value.into() }
    }
}

impl From<&Uuid> for EventId {
    fn from(value: &Uuid) -> Self {
        Self {
            id: value.to_string(),
        }
    }
}

impl From<String> for EventId {
    fn from(value: String) -> Self {
        Self { id: value }
    }
}

impl From<&String> for EventId {
    fn from(value: &String) -> Self {
        Self {
            id: value.to_string(),
        }
    }
}

impl From<&str> for EventId {
    fn from(value: &str) -> Self {
        Self {
            id: value.to_string(),
        }
    }
}

impl From<EventId> for String {
    fn from(value: EventId) -> Self {
        value.id
    }
}

impl From<&EventId> for String {
    fn from(value: &EventId) -> Self {
        value.id.to_owned()
    }
}

#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub(crate) struct Event {
    pub id: EventId,
    time: SystemTime,
}

impl Debug for Event {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let time_str = format!("{}", DateTime::<Local>::from(self.time));
        f.debug_struct("Event")
            .field("id", &self.id)
            .field("time", &time_str)
            .finish()
    }
}

impl Event {
    pub fn new(id: impl Into<EventId>, time: SystemTime) -> Self {
        Self {
            id: id.into(),
            time,
        }
    }

    pub fn with_id(id: impl Into<EventId>) -> Self {
        Self {
            id: id.into(),
            time: SystemTime::now(),
        }
    }

    pub fn with_time(time: SystemTime) -> Self {
        Self {
            id: EventId::default(),
            time,
        }
    }

    pub fn id(&self) -> EventId {
        self.id.clone()
    }

    pub fn time(&self) -> SystemTime {
        self.time
    }
}

impl Default for Event {
    fn default() -> Self {
        Self::new(EventId::default(), SystemTime::now())
    }
}

impl From<SystemTime> for Event {
    fn from(value: SystemTime) -> Self {
        Self::with_time(value)
    }
}

impl From<&SystemTime> for Event {
    fn from(value: &SystemTime) -> Self {
        Self::with_time(*value)
    }
}

impl From<Event> for EventId {
    fn from(value: Event) -> EventId {
        value.id
    }
}

impl From<TaskId> for EventId {
    fn from(value: TaskId) -> EventId {
        Self { id: value.id }
    }
}

impl From<&Event> for EventId {
    fn from(value: &Event) -> Self {
        value.id.clone()
    }
}

impl From<Event> for SystemTime {
    fn from(value: Event) -> SystemTime {
        value.time
    }
}

impl From<&Event> for SystemTime {
    fn from(value: &Event) -> Self {
        value.time
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use uuid::Uuid;

    #[test]
    fn type_convertors() {
        let uuid_id = Uuid::new_v4();
        let str_id = uuid_id.to_string();
        let event_id = EventId { id: str_id.clone() };

        assert_eq!(EventId::from(uuid_id), event_id);
        assert_eq!(EventId::from(&uuid_id), event_id);
        assert_eq!(EventId::from(str_id.clone()), event_id);
        assert_eq!(EventId::from(&str_id), event_id);
        assert_eq!(
            EventId::from("EVENT_ID"),
            EventId {
                id: "EVENT_ID".to_string()
            }
        );

        let id = String::from("TEST");
        let now = SystemTime::now();
        let event = Event::new(id.clone(), now);
        let task_id = TaskId::from(id.clone());

        assert_eq!(String::from(&event_id), str_id);
        assert_eq!(String::from(event_id), str_id);

        assert_eq!(Event::from(now).time, now);
        assert_eq!(Event::from(&now).time, now);

        assert_eq!(EventId::from(event.clone()).id, id);
        assert_eq!(EventId::from(&event).id, id);

        assert_eq!(EventId::from(task_id).id, id);

        assert_eq!(SystemTime::from(event.clone()), now);
        assert_eq!(SystemTime::from(&event), now);
    }

    #[test]
    fn constructors() {
        let id = String::from("TEST");
        let now = SystemTime::now();

        assert_ne!(EventId::default(), EventId::default());
        assert_eq!(Event::with_id(id.clone()).id(), EventId::from(id.clone()));
        assert_eq!(Event::with_time(now).time(), now);
    }

    #[test]
    fn debug_formatter() {
        let id = String::from("TEST");
        let now = SystemTime::now();

        assert_eq!(
            format!("{:?}", Event::new(id, now)),
            format!(
                "Event {{ id: EventId {{ id: \"TEST\" }}, time: \"{}\" }}",
                DateTime::<Local>::from(now)
            )
        );
    }
}