1mod config;
2mod handles;
3mod protocol;
4#[cfg(feature = "std")]
5mod tcp;
6
7#[cfg(feature = "std")]
8pub use tcp::{
9 DeliveredMessage, OBSERVABILITY_CHANNEL, PushClient, PushWriter, PushedFrame,
10 SubscriptionStream, TcpRemoteTransport,
11};
12
13pub use config::{SdkConfig, build_channel_handle, build_conversation_handle};
14pub use handles::{
15 RemoteChannelHandle, RemoteConversationHandle, SdkChannelHandle, SdkConversationHandle,
16};
17
18#[cfg(test)]
19mod tests;
20
21use alloc::string::{String, ToString};
22use alloc::sync::Arc;
23use core::time::Duration;
24
25use crate::connection::{ConnectionPoolConfig, ReconnectConfig, ReconnectJitter};
26use crate::{ConversationId, SdkError};
27
28use self::protocol::{ProtocolRemoteTransport, RemoteTransport};
29
30#[derive(Clone, Debug, PartialEq, Eq)]
32pub struct ServerAddress(String);
33
34impl ServerAddress {
35 pub fn new(value: impl Into<String>) -> Result<Self, SdkError> {
41 let value = value.into();
42 if value.trim().is_empty() {
43 return Err(connection_error("remote mode requires a server address"));
44 }
45 Ok(Self(value))
46 }
47
48 #[must_use]
50 pub fn as_str(&self) -> &str {
51 self.0.as_str()
52 }
53}
54
55#[derive(Clone, Debug)]
57pub struct RemoteConfig {
58 pub server_address: ServerAddress,
60 pub channel_name: String,
62 pub conversation_id: ConversationId,
64 pub pool_config: ConnectionPoolConfig,
66 pub reconnect_config: ReconnectConfig,
68 transport: Arc<dyn RemoteTransport>,
69}
70
71impl RemoteConfig {
72 pub fn new(
78 server_address: impl Into<String>,
79 channel_name: impl Into<String>,
80 conversation_id: impl Into<ConversationId>,
81 pool_config: ConnectionPoolConfig,
82 ) -> Result<Self, SdkError> {
83 Ok(Self {
84 server_address: ServerAddress::new(server_address)?,
85 channel_name: channel_name.into(),
86 conversation_id: conversation_id.into(),
87 pool_config: pool_config.validate()?,
88 reconnect_config: ReconnectConfig::default(),
89 transport: Arc::new(ProtocolRemoteTransport),
90 })
91 }
92
93 #[must_use]
95 pub const fn with_reconnect_config(mut self, reconnect_config: ReconnectConfig) -> Self {
96 self.reconnect_config = reconnect_config;
97 self
98 }
99
100 #[cfg(feature = "std")]
112 pub fn connect_tcp(mut self) -> Result<Self, SdkError> {
113 let transport = self::tcp::TcpRemoteTransport::connect(&self.server_address)?;
114 self.transport = Arc::new(transport);
115 Ok(self)
116 }
117
118 #[cfg(feature = "std")]
133 pub fn connect_tcp_with_auth(mut self, auth_token: &[u8]) -> Result<Self, SdkError> {
134 let transport =
135 self::tcp::TcpRemoteTransport::connect_with_auth(&self.server_address, auth_token)?;
136 self.transport = Arc::new(transport);
137 Ok(self)
138 }
139}
140
141#[derive(Clone, Copy, Debug, Default)]
143pub struct NoJitter;
144
145impl ReconnectJitter for NoJitter {
146 fn jitter(&mut self, attempt: u32, capped_delay: Duration) -> Duration {
147 core::hint::black_box((attempt, capped_delay));
148 Duration::ZERO
149 }
150}
151
152fn connection_error(description: &str) -> SdkError {
153 SdkError::Connection {
154 description: description.to_string(),
155 }
156}