Skip to main content

made_core/events/
task_dispatched.rs

1//! [`TaskDispatchedEvent`] — published when MADE routes a
2//! task to its council.
3
4use serde::{Deserialize, Serialize};
5
6use crate::events::envelope::EventEnvelope;
7use crate::value_objects::{EventId, Specialty, TaskId};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct TaskDispatchedEvent {
11    #[serde(flatten)]
12    envelope: EventEnvelope,
13    task_id: TaskId,
14    specialty: Specialty,
15    trigger_event_id: Option<EventId>,
16}
17
18impl TaskDispatchedEvent {
19    #[must_use]
20    pub fn new(
21        envelope: EventEnvelope,
22        task_id: TaskId,
23        specialty: Specialty,
24        trigger_event_id: Option<EventId>,
25    ) -> Self {
26        Self {
27            envelope,
28            task_id,
29            specialty,
30            trigger_event_id,
31        }
32    }
33
34    #[must_use]
35    pub fn envelope(&self) -> &EventEnvelope {
36        &self.envelope
37    }
38    #[must_use]
39    pub fn task_id(&self) -> &TaskId {
40        &self.task_id
41    }
42    #[must_use]
43    pub fn specialty(&self) -> &Specialty {
44        &self.specialty
45    }
46    #[must_use]
47    pub fn trigger_event_id(&self) -> Option<&EventId> {
48        self.trigger_event_id.as_ref()
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use time::macros::datetime;
56
57    fn env() -> EventEnvelope {
58        EventEnvelope::new(
59            EventId::new("e1").unwrap(),
60            datetime!(2026-04-15 12:00:00 UTC),
61            "made",
62            None,
63        )
64        .unwrap()
65    }
66
67    #[test]
68    fn accessors_return_fields() {
69        let ev = TaskDispatchedEvent::new(
70            env(),
71            TaskId::new("t1").unwrap(),
72            Specialty::new("triage").unwrap(),
73            Some(EventId::new("trig").unwrap()),
74        );
75        assert_eq!(ev.task_id().as_str(), "t1");
76        assert_eq!(ev.specialty().as_str(), "triage");
77        assert_eq!(ev.trigger_event_id().unwrap().as_str(), "trig");
78        assert_eq!(ev.envelope().source(), "made");
79    }
80
81    #[test]
82    fn trigger_event_id_may_be_absent() {
83        let ev = TaskDispatchedEvent::new(
84            env(),
85            TaskId::new("t").unwrap(),
86            Specialty::new("s").unwrap(),
87            None,
88        );
89        assert!(ev.trigger_event_id().is_none());
90    }
91}