Skip to main content

syncweb_core/node/
gossip_service.rs

1use bytes::Bytes;
2use iroh::PublicKey;
3use iroh_gossip::{
4    TopicId,
5    api::{GossipReceiver, GossipSender, GossipTopic},
6    net::Gossip,
7};
8
9use crate::error::{Result, SyncwebError};
10
11#[derive(Clone)]
12pub struct GossipService {
13    gossip: Gossip,
14}
15
16impl GossipService {
17    #[must_use]
18    pub fn new(gossip: &Gossip) -> Self {
19        Self { gossip: gossip.clone() }
20    }
21
22    #[must_use]
23    pub const fn inner(&self) -> &Gossip {
24        &self.gossip
25    }
26
27    /// # Errors
28    ///
29    /// Returns an error if subscribing to the topic fails.
30    pub async fn subscribe(&self, topic: TopicId, bootstrap: Vec<PublicKey>) -> Result<GossipTopic> {
31        self.gossip
32            .subscribe(topic, bootstrap)
33            .await
34            .map_err(|error| SyncwebError::operation("failed to subscribe to gossip topic", error))
35    }
36
37    /// # Errors
38    ///
39    /// Returns an error if subscribing or joining the topic fails.
40    pub async fn subscribe_and_join(&self, topic: TopicId, bootstrap: Vec<PublicKey>) -> Result<GossipTopic> {
41        self.gossip
42            .subscribe_and_join(topic, bootstrap)
43            .await
44            .map_err(|error| SyncwebError::operation("failed to join gossip topic", error))
45    }
46
47    /// # Errors
48    ///
49    /// Returns an error if the message cannot be published to the topic.
50    pub async fn publish(&self, sender: &GossipSender, message: impl AsRef<[u8]>) -> Result<()> {
51        sender
52            .broadcast(Bytes::copy_from_slice(message.as_ref()))
53            .await
54            .map_err(|error| SyncwebError::operation("failed to publish gossip message", error))
55    }
56
57    #[must_use]
58    pub fn split(topic: GossipTopic) -> (GossipSender, GossipReceiver) {
59        topic.split()
60    }
61
62    #[must_use]
63    pub const fn event_stream(topic: GossipTopic) -> GossipTopic {
64        topic
65    }
66}