grafbase_sdk/host_io/nats.rs
1//! Client interface for interacting with NATS messaging system
2//!
3//! This module provides a high-level client for connecting to and interacting with NATS servers.
4//! It supports both authenticated and unauthenticated connections to one or more NATS servers.
5
6use crate::wit::NatsAuth;
7
8/// A client for interacting with NATS servers
9pub struct NatsClient {
10 inner: crate::wit::NatsClient,
11}
12
13impl NatsClient {
14 /// Publishes a message to the specified NATS subject
15 ///
16 /// # Arguments
17 ///
18 /// * `subject` - The NATS subject to publish to
19 /// * `payload` - The message payload as a byte slice
20 ///
21 /// # Returns
22 ///
23 /// Result indicating success or an error if the publish fails
24 pub fn publish<S>(&self, subject: &str, payload: &S) -> Result<(), Box<dyn std::error::Error>>
25 where
26 S: serde::Serialize,
27 {
28 Ok(self.inner.publish(subject, &serde_json::to_vec(payload).unwrap())?)
29 }
30
31 /// Subscribes to messages on the specified NATS subject
32 ///
33 /// # Arguments
34 ///
35 /// * `subject` - The NATS subject to subscribe to
36 ///
37 /// # Returns
38 ///
39 /// Result containing the subscription or an error if subscription fails
40 pub fn subscribe(&self, subject: &str) -> Result<NatsSubscriber, Box<dyn std::error::Error>> {
41 Ok(self.inner.subscribe(subject).map(Into::into)?)
42 }
43}
44
45/// A subscription to a NATS subject that receives messages published to that subject
46pub struct NatsSubscriber {
47 inner: crate::wit::NatsSubscriber,
48}
49
50impl From<crate::wit::NatsSubscriber> for NatsSubscriber {
51 fn from(inner: crate::wit::NatsSubscriber) -> Self {
52 NatsSubscriber { inner }
53 }
54}
55
56impl NatsSubscriber {
57 /// Gets the next message from the subscription
58 ///
59 /// # Returns
60 ///
61 /// Result containing the next message or an error if retrieval fails
62 pub fn next(&self) -> Option<NatsMessage> {
63 self.inner.next().map(Into::into)
64 }
65}
66
67/// A message received from a NATS subscription containing the payload data
68pub struct NatsMessage {
69 inner: crate::wit::NatsMessage,
70}
71
72impl From<crate::wit::NatsMessage> for NatsMessage {
73 fn from(inner: crate::wit::NatsMessage) -> Self {
74 NatsMessage { inner }
75 }
76}
77
78impl NatsMessage {
79 /// Gets the payload data of the message
80 ///
81 /// # Returns
82 ///
83 /// Result containing the payload data or an error if retrieval fails
84 pub fn payload<S>(&self) -> anyhow::Result<S>
85 where
86 S: for<'de> serde::Deserialize<'de>,
87 {
88 Ok(serde_json::from_slice(&self.inner.payload)?)
89 }
90
91 /// Gets the subject of the message
92 ///
93 /// # Returns
94 ///
95 /// The NATS subject this message was published to
96 pub fn subject(&self) -> &str {
97 &self.inner.subject
98 }
99}
100
101/// Connects to one or more NATS servers
102///
103/// # Arguments
104///
105/// * `servers` - Iterator of server addresses to connect to
106///
107/// # Returns
108///
109/// Result containing the connected NATS client or an error if connection fails
110pub fn connect(servers: impl IntoIterator<Item = impl ToString>) -> Result<NatsClient, Box<dyn std::error::Error>> {
111 let servers: Vec<_> = servers.into_iter().map(|s| s.to_string()).collect();
112 let inner = crate::wit::NatsClient::connect(&servers, None)?;
113
114 Ok(NatsClient { inner })
115}
116
117/// Connects to one or more NATS servers with authentication
118///
119/// # Arguments
120///
121/// * `servers` - Iterator of server addresses to connect to
122/// * `auth` - Authentication credentials for connecting to the servers
123///
124/// # Returns
125///
126/// Result containing the connected NATS client or an error if connection fails
127pub fn connect_with_auth(
128 servers: impl IntoIterator<Item = impl ToString>,
129 auth: &NatsAuth,
130) -> Result<NatsClient, Box<dyn std::error::Error>> {
131 let servers: Vec<_> = servers.into_iter().map(|s| s.to_string()).collect();
132 let inner = crate::wit::NatsClient::connect(&servers, Some(auth))?;
133
134 Ok(NatsClient { inner })
135}