pubsub_bus/
publisher.rs

1// *************************************************************************
2//
3// Copyright (c) 2025 Andrei Gramakov. All rights reserved.
4//
5// This file is licensed under the terms of the MIT license.
6// For a copy, see: https://opensource.org/licenses/MIT
7//
8// site:    https://agramakov.me
9// e-mail:  mail@agramakov.me
10//
11// *************************************************************************
12use crate::{event_bus_internal::EventBusInternal, EventBus};
13use std::sync::Arc;
14
15#[cfg(test)]
16mod tests;
17
18/// EventEmitter is a struct that can be used to publish events to the event bus.
19/// It supposed to be used by the publisher.
20pub struct EventEmitter<ContentType, TopicId: std::cmp::PartialEq + Clone> {
21    event_bus: Option<Arc<EventBusInternal<ContentType, TopicId>>>,
22    source_id: u64,
23}
24
25impl<ContentType, TopicId: std::cmp::PartialEq + Clone> EventEmitter<ContentType, TopicId> {
26    pub fn with_bus(bus: &EventBus<ContentType, TopicId>) -> Self {
27        Self {
28            event_bus: Some(bus.get_internal()),
29            source_id: 0,
30        }
31    }
32
33    pub fn new() -> Self {
34        Self {
35            event_bus: None,
36            source_id: 0,
37        }
38    }
39
40    /// Set the event bus for the emitter.
41    /// If source_id is None, the publisher will be assigned a unique id.
42    pub fn set_bus(
43        &mut self,
44        bus: &EventBus<ContentType, TopicId>,
45        source_id: Option<u64>,
46    ) -> Result<(), &'static str> {
47        let internal_bus = bus.get_internal();
48        let id = internal_bus.register_publisher(source_id)?;
49
50        self.source_id = id;
51        self.event_bus = Some(bus.get_internal());
52        Ok(())
53    }
54
55    /// Publish an event to the event bus.
56    /// If topic_id is None, the event will be sent to all subscribers.
57    pub fn publish(&mut self, content: ContentType, topic_id: Option<TopicId>) {
58        match &mut self.event_bus {
59            None => {
60                panic!("Publisher has no bus");
61            }
62            Some(bus) => {
63                bus.publish(content, topic_id, self.source_id);
64            }
65        }
66    }
67}
68
69/// Publisher is a trait that defines a publisher to the event bus.
70/// Publisher is expected to care an EventEmitter.
71pub trait Publisher<ContentType, TopicId: std::cmp::PartialEq + Clone> {
72    /// Get the emitter of the publisher. Has to be implemented by the publisher.
73    fn get_mut_emitter(&mut self) -> &mut EventEmitter<ContentType, TopicId>;
74
75    /// Default implementation to Publish an event to the event bus.
76    /// If topic_id is None, the event will be sent to all subscribers.
77    fn publish(&mut self, content: ContentType, topic_id: Option<TopicId>) {
78        self.get_mut_emitter().publish(content, topic_id);
79    }
80}