misskey_websocket/client/
builder.rs1use std::convert::TryInto;
2use std::result::Result as StdResult;
3use std::time::Duration;
4
5use crate::broker::{ReconnectCondition, ReconnectConfig};
6use crate::client::WebSocketClient;
7use crate::error::{Error, Result};
8
9use url::Url;
10
11#[derive(Debug, Clone)]
12struct WebSocketClientBuilderInner {
13 url: Url,
14 reconnect: ReconnectConfig,
15}
16
17#[derive(Debug, Clone)]
19pub struct WebSocketClientBuilder {
20 inner: Result<WebSocketClientBuilderInner>,
21}
22
23trait ResultExt<T, E> {
24 fn and_then_mut<F>(&mut self, op: F)
25 where
26 F: FnOnce(&mut T) -> StdResult<(), E>;
27}
28
29impl<T, E> ResultExt<T, E> for StdResult<T, E> {
30 fn and_then_mut<F>(&mut self, f: F)
31 where
32 F: FnOnce(&mut T) -> StdResult<(), E>,
33 {
34 if let Ok(x) = self {
35 if let Err(e) = f(x) {
36 *self = Err(e);
37 }
38 }
39 }
40}
41
42impl WebSocketClientBuilder {
43 pub fn new<T>(url: T) -> Self
47 where
48 T: TryInto<Url>,
49 T::Error: Into<Error>,
50 {
51 let inner = url
52 .try_into()
53 .map_err(Into::into)
54 .map(|url| WebSocketClientBuilderInner {
55 url,
56 reconnect: ReconnectConfig::default(),
57 });
58
59 WebSocketClientBuilder { inner }
60 }
61
62 pub fn with_host<S>(host: S) -> Self
67 where
68 S: AsRef<str>,
69 {
70 let url = format!("wss://{}/streaming", host.as_ref());
71 WebSocketClientBuilder::new(url.as_str())
72 }
73
74 pub fn token<S>(&mut self, token: S) -> &mut Self
78 where
79 S: AsRef<str>,
80 {
81 self.query("i", token)
82 }
83
84 pub fn query<S1, S2>(&mut self, key: S1, value: S2) -> &mut Self
86 where
87 S1: AsRef<str>,
88 S2: AsRef<str>,
89 {
90 self.inner.and_then_mut(|inner| {
91 inner
92 .url
93 .query_pairs_mut()
94 .append_pair(key.as_ref(), value.as_ref());
95 Ok(())
96 });
97 self
98 }
99
100 pub fn auto_reconnect(&mut self, enable: bool) -> &mut Self {
107 if enable {
108 self.reconnect_condition(ReconnectCondition::unexpected_reset())
109 } else {
110 self.reconnect_condition(ReconnectCondition::never())
111 }
112 }
113
114 pub fn reconnect_secs(&mut self, secs: u64) -> &mut Self {
116 self.inner.and_then_mut(|inner| {
117 inner.reconnect.interval = Duration::from_secs(secs);
118 Ok(())
119 });
120 self
121 }
122
123 pub fn reconnect_interval(&mut self, interval: Duration) -> &mut Self {
125 self.inner.and_then_mut(|inner| {
126 inner.reconnect.interval = interval;
127 Ok(())
128 });
129 self
130 }
131
132 pub fn reconnect_condition(&mut self, condition: ReconnectCondition) -> &mut Self {
134 self.inner.and_then_mut(|inner| {
135 inner.reconnect.condition = condition;
136 Ok(())
137 });
138 self
139 }
140
141 pub fn reconnect_retry_send(&mut self, enable: bool) -> &mut Self {
143 self.inner.and_then_mut(|inner| {
144 inner.reconnect.retry_send = enable;
145 Ok(())
146 });
147 self
148 }
149
150 pub async fn connect(&self) -> Result<WebSocketClient> {
152 let WebSocketClientBuilderInner { url, reconnect } = match self.inner.clone() {
153 Err(e) => return Err(e),
154 Ok(inner) => inner,
155 };
156
157 WebSocketClient::connect_with_config(url, reconnect).await
158 }
159}