use-event-envelope 0.1.0

Generic event envelope composed from RustUse event primitives.
Documentation
#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]

use use_event_id::EventId;
use use_event_kind::EventKind;
use use_event_metadata::EventMetadata;
use use_event_name::EventName;
use use_event_source::EventSource;
use use_event_target::EventTarget;
use use_event_timestamp::EventTimestamp;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EventEnvelope<P> {
    pub id: EventId,
    pub name: EventName,
    pub kind: EventKind,
    pub source: EventSource,
    pub target: Option<EventTarget>,
    pub timestamp: EventTimestamp,
    pub metadata: EventMetadata,
    pub payload: P,
}

impl<P> EventEnvelope<P> {
    pub fn new(name: EventName, kind: EventKind, source: EventSource, payload: P) -> Self {
        Self {
            id: EventId::default(),
            name,
            kind,
            source,
            target: None,
            timestamp: EventTimestamp::now(),
            metadata: EventMetadata::default(),
            payload,
        }
    }

    pub fn with_id(mut self, id: impl Into<EventId>) -> Self {
        self.id = id.into();
        self
    }

    pub fn with_target(mut self, target: impl Into<EventTarget>) -> Self {
        self.target = Some(target.into());
        self
    }

    pub fn with_metadata(mut self, metadata: EventMetadata) -> Self {
        self.metadata = metadata;
        self
    }

    pub fn with_timestamp(mut self, timestamp: EventTimestamp) -> Self {
        self.timestamp = timestamp;
        self
    }
}

#[cfg(test)]
mod tests {
    use super::EventEnvelope;
    use std::time::SystemTime;
    use use_event_id::EventId;
    use use_event_kind::EventKind;
    use use_event_metadata::EventMetadata;
    use use_event_name::EventName;
    use use_event_source::EventSource;
    use use_event_target::EventTarget;
    use use_event_timestamp::EventTimestamp;

    #[test]
    fn creates_default_envelope() {
        let event = EventEnvelope::new(
            EventName::new("command.started"),
            EventKind::Started,
            EventSource::new("cli"),
            "rustuse build",
        );

        assert_eq!(event.id, EventId::default());
        assert_eq!(event.name.as_str(), "command.started");
        assert_eq!(event.kind, EventKind::Started);
        assert_eq!(event.source.as_str(), "cli");
        assert_eq!(event.target, None);
        assert_eq!(event.payload, "rustuse build");
    }

    #[test]
    fn applies_builder_values() {
        let metadata = EventMetadata::with_entry("trace_id", "abc");
        let timestamp = EventTimestamp::from_system_time(SystemTime::UNIX_EPOCH);
        let event = EventEnvelope::new(
            EventName::new("command.started"),
            EventKind::Started,
            EventSource::new("cli"),
            "rustuse build",
        )
        .with_id("evt-001")
        .with_target(EventTarget::new("worker"))
        .with_metadata(metadata)
        .with_timestamp(timestamp);

        assert_eq!(event.id.as_str(), "evt-001");
        assert_eq!(
            event.target.as_ref().map(EventTarget::as_str),
            Some("worker")
        );
        assert_eq!(event.metadata.get("trace_id"), Some("abc"));
        assert_eq!(event.timestamp.as_system_time(), SystemTime::UNIX_EPOCH);
    }
}