Skip to main content

ddd_toolkit_core/domain/
event.rs

1use std::fmt::Debug;
2
3/// Something that happened in the domain, recorded by an
4/// [`crate::domain::AggregateRoot`] and later published through an
5/// [`crate::port::event::EventDispatcher`].
6///
7/// # Examples
8///
9/// See [`AggregateRoot`](crate::domain::AggregateRoot#examples) for a worked
10/// example of recording and draining `DomainEvent`s.
11pub trait DomainEvent: Debug + Send + Sync + 'static {}
12
13#[cfg(test)]
14mod test {
15    use super::*;
16
17    #[derive(Debug)]
18    struct TestEvent;
19
20    impl DomainEvent for TestEvent {}
21
22    #[test]
23    fn test_double_implements_domain_event() {
24        let _event = TestEvent;
25    }
26
27    #[test]
28    fn domain_event_is_dyn_compatible() {
29        let _event: Box<dyn DomainEvent> = Box::new(TestEvent);
30    }
31
32    #[test]
33    fn debug_format_works_via_trait_object() {
34        let event: &dyn DomainEvent = &TestEvent;
35
36        assert_eq!(format!("{event:?}"), "TestEvent");
37    }
38
39    #[test]
40    fn trait_object_is_send_and_sync() {
41        fn assert_send_sync<T: Send + Sync + ?Sized>() {}
42
43        assert_send_sync::<dyn DomainEvent>();
44    }
45
46    #[test]
47    fn test_double_with_fields_implements_domain_event() {
48        #[derive(Debug)]
49        struct TestEventWithFields {
50            id: String,
51        }
52
53        impl DomainEvent for TestEventWithFields {}
54
55        let event = TestEventWithFields {
56            id: "event-1".to_string(),
57        };
58        assert_eq!(event.id, "event-1");
59
60        let event: &dyn DomainEvent = &event;
61        assert_eq!(
62            format!("{event:?}"),
63            r#"TestEventWithFields { id: "event-1" }"#
64        );
65    }
66}