wsio_client/
lib.rs

1use std::{
2    fmt::Display,
3    sync::Arc,
4};
5
6use anyhow::{
7    Result,
8    bail,
9};
10use serde::{
11    Serialize,
12    de::DeserializeOwned,
13};
14use tokio_util::sync::CancellationToken;
15use url::Url;
16pub use wsio_core as core;
17
18mod builder;
19mod config;
20mod runtime;
21pub mod session;
22
23use crate::{
24    builder::WsIoClientBuilder,
25    core::traits::task::spawner::TaskSpawner,
26    runtime::WsIoClientRuntime,
27    session::WsIoClientSession,
28};
29
30// Structs
31#[derive(Clone)]
32pub struct WsIoClient(Arc<WsIoClientRuntime>);
33
34impl WsIoClient {
35    // Public methods
36    pub fn builder<U>(url: U) -> Result<WsIoClientBuilder>
37    where
38        U: TryInto<Url>,
39        U::Error: Display,
40    {
41        let url = match url.try_into() {
42            Ok(url) => url,
43            Err(err) => bail!("Invalid URL: {err}"),
44        };
45
46        if url.scheme() == "wss"
47            && !cfg!(any(
48                feature = "tls-native",
49                feature = "tls-rustls-native",
50                feature = "tls-rustls-webpki",
51            ))
52        {
53            bail!("TLS is required for wss:// URLs, but no TLS feature is enabled");
54        }
55
56        WsIoClientBuilder::new(url)
57    }
58
59    pub fn cancel_token(&self) -> Arc<CancellationToken> {
60        self.0.cancel_token()
61    }
62
63    pub async fn connect(&self) {
64        self.0.connect().await
65    }
66
67    pub async fn disconnect(&self) {
68        self.0.disconnect().await
69    }
70
71    pub async fn emit<D: Serialize>(&self, event: impl AsRef<str>, data: Option<&D>) -> Result<()> {
72        self.0.emit(event.as_ref(), data).await
73    }
74
75    #[inline]
76    pub fn is_session_ready(&self) -> bool {
77        self.0.is_session_ready()
78    }
79
80    #[inline]
81    pub fn off(&self, event: impl AsRef<str>) {
82        self.0.off(event.as_ref());
83    }
84
85    #[inline]
86    pub fn off_by_handler_id(&self, event: impl AsRef<str>, handler_id: u32) {
87        self.0.off_by_handler_id(event.as_ref(), handler_id);
88    }
89
90    #[inline]
91    pub fn on<H, Fut, D>(&self, event: impl AsRef<str>, handler: H) -> u32
92    where
93        H: Fn(Arc<WsIoClientSession>, Arc<D>) -> Fut + Send + Sync + 'static,
94        Fut: Future<Output = Result<()>> + Send + 'static,
95        D: DeserializeOwned + Send + Sync + 'static,
96    {
97        self.0.on(event.as_ref(), handler)
98    }
99
100    #[inline]
101    pub fn spawn_task<F: Future<Output = Result<()>> + Send + 'static>(&self, future: F) {
102        self.0.spawn_task(future);
103    }
104}