srad_client/traits.rs
1use async_trait::async_trait;
2use srad_types::{
3 payload::Payload,
4 topic::{DeviceTopic, NodeTopic, StateTopic, TopicFilter},
5};
6
7use crate::{Event, LastWill, StatePayload};
8
9/// A trait for implementing a type that acts as a Sparkplug Client
10#[async_trait]
11pub trait Client {
12 /// Disconnects the client.
13 async fn disconnect(&self) -> Result<(), ()>;
14
15 /// Publishes a state message to the specified state topic.
16 ///
17 /// This method will yield to the async runtime until the message is accepted by the client
18 async fn publish_state_message(
19 &self,
20 topic: StateTopic,
21 payload: StatePayload,
22 ) -> Result<(), ()>;
23
24 /// Attempts to publish a state message to the specified state topic.
25 ///
26 /// Unlike `publish_state_message`, this method may return early if the client cannot process the message
27 /// e.g the message queue is full.
28 async fn try_publish_state_message(
29 &self,
30 topic: StateTopic,
31 payload: StatePayload,
32 ) -> Result<(), ()>;
33
34 /// Publishes a message to a node-specific topic.
35 ///
36 /// This method will yield to the async runtime until the message is accepted by the client
37 async fn publish_node_message(&self, topic: NodeTopic, payload: Payload) -> Result<(), ()>;
38
39 /// Attempts to publish a message to a node-specific topic.
40 ///
41 /// Unlike `publish_node_message`, this method may return early if the client cannot process the message
42 /// e.g the message queue is full.
43 async fn try_publish_node_message(&self, topic: NodeTopic, payload: Payload) -> Result<(), ()>;
44
45 /// Publishes a message to a device-specific topic.
46 ///
47 /// This method will yield to the async runtime until the message is accepted by the client
48 async fn publish_device_message(&self, topic: DeviceTopic, payload: Payload) -> Result<(), ()>;
49
50 /// Attempts to publish a message to a device-specific topic.
51 ///
52 /// Unlike `publish_device_message`, this method may return early if the client cannot process the message
53 /// e.g the message queue is full.
54 async fn try_publish_device_message(
55 &self,
56 topic: DeviceTopic,
57 payload: Payload,
58 ) -> Result<(), ()>;
59
60 /// Subscribes to a single topic.
61 ///
62 /// This is a convenience method that calls `subscribe_many` with a single topic.
63 async fn subscribe(&self, topic: TopicFilter) -> Result<(), ()> {
64 self.subscribe_many(vec![topic]).await
65 }
66
67 /// Subscribes to multiple topics in a single operation.
68 async fn subscribe_many(&self, topics: Vec<TopicFilter>) -> Result<(), ()>;
69}
70
71pub type DynClient = dyn Client + Send + Sync;
72
73/// A trait for implementing a type that acts as a Sparkplug Client's EventLoop
74#[async_trait]
75pub trait EventLoop {
76 /// Poll the EventLoop for an event
77 /// Continuing to poll will reconnect if there is
78 /// a disconnection.
79 /// **NOTE** Don't block this while iterating
80 async fn poll(&mut self) -> Event;
81 ///Set the last will to be used on the next connection
82 fn set_last_will(&mut self, will: LastWill);
83}
84
85pub type DynEventLoop = dyn EventLoop + Send;