1use liminal_sdk::{
10 DeliveredMessage, RemoteConfig, SdkError, SubscriptionStream, WebSocketSubscriptionStream,
11};
12
13pub type Close = Box<dyn Fn() -> Result<(), SdkError> + Send + Sync>;
15
16#[must_use]
18pub fn is_websocket(address: &str) -> bool {
19 address.starts_with("ws://") || address.starts_with("wss://")
20}
21
22pub fn connect(
28 address: &str,
29 config: RemoteConfig,
30 credential: &[u8],
31) -> Result<RemoteConfig, SdkError> {
32 if is_websocket(address) {
33 config.connect_websocket_with_auth(credential)
34 } else {
35 config.connect_tcp_with_auth(credential)
36 }
37}
38
39#[derive(Debug)]
41pub enum Subscription {
42 Tcp(SubscriptionStream),
44 Ws(WebSocketSubscriptionStream),
46}
47
48impl Subscription {
49 pub fn open(address: &str, channel: &str, credential: &[u8]) -> Result<Self, SdkError> {
54 if is_websocket(address) {
55 WebSocketSubscriptionStream::open_with_auth(address, channel, Vec::new(), credential)
56 .map(Self::Ws)
57 } else {
58 SubscriptionStream::open_with_auth(address, channel, Vec::new(), credential)
59 .map(Self::Tcp)
60 }
61 }
62
63 pub fn recv(&self) -> Result<DeliveredMessage, SdkError> {
68 match self {
69 Self::Tcp(stream) => stream.recv(),
70 Self::Ws(stream) => stream.recv().map(DeliveredMessage::from),
71 }
72 }
73
74 pub fn recv_timeout(&self, timeout: std::time::Duration) -> Result<DeliveredMessage, SdkError> {
79 match self {
80 Self::Tcp(stream) => stream.recv_timeout(timeout),
81 Self::Ws(stream) => stream.recv_timeout(timeout).map(DeliveredMessage::from),
82 }
83 }
84
85 pub fn close_handle(&self) -> Result<Close, SdkError> {
90 Ok(match self {
91 Self::Tcp(stream) => Box::new(stream.close_handle()?),
92 Self::Ws(stream) => Box::new(stream.close_handle()?),
93 })
94 }
95}
96
97#[cfg(test)]
98#[path = "rail_link_tests.rs"]
99mod tests;