clankerdiff_client/
transport.rs1use crate::{
2 ClientError,
3 protocol::{
4 client::{ClientCommand, DocumentCache, LocalClientTransport},
5 server::{ServerEvent, ServerMessage},
6 shared::LocalEnd,
7 },
8};
9use std::future::Future;
10
11#[cfg(feature = "websocket")]
12use crate::ConnectionHeader;
13
14#[cfg(feature = "websocket")]
15#[cfg_attr(not(target_arch = "wasm32"), path = "transport/native.rs")]
16#[cfg_attr(target_arch = "wasm32", path = "transport/web.rs")]
17mod ws;
18
19#[cfg(not(target_arch = "wasm32"))]
20pub trait MaybeSend: Send {}
21#[cfg(not(target_arch = "wasm32"))]
22impl<T: Send> MaybeSend for T {}
23#[cfg(target_arch = "wasm32")]
24pub trait MaybeSend {}
25#[cfg(target_arch = "wasm32")]
26impl<T> MaybeSend for T {}
27
28pub trait ClientMessageTransport: MaybeSend + 'static {
29 fn send(
30 &mut self,
31 command: ClientCommand,
32 ) -> impl Future<Output = Result<(), ClientError>> + MaybeSend;
33 fn recv(&mut self) -> impl Future<Output = Result<ServerMessage, ClientError>> + MaybeSend;
34 fn close(&mut self) -> impl Future<Output = ()> + MaybeSend;
35}
36
37pub(crate) trait Transport: MaybeSend + 'static {
38 fn send(
39 &mut self,
40 command: ClientCommand,
41 ) -> impl Future<Output = Result<(), ClientError>> + MaybeSend;
42 fn recv(&mut self) -> impl Future<Output = Result<ServerEvent, ClientError>> + MaybeSend;
43 fn close(&mut self) -> impl Future<Output = ()> + MaybeSend;
44
45 fn reconnects(&self) -> bool {
46 false
47 }
48
49 fn reconnect(&mut self) -> impl Future<Output = Result<(), ClientError>> + MaybeSend {
50 async { Err(ClientError::Disconnected) }
51 }
52}
53
54impl Transport for LocalClientTransport {
55 async fn send(&mut self, command: ClientCommand) -> Result<(), ClientError> {
56 LocalEnd::send(self, command)
57 .await
58 .map_err(|_| ClientError::Disconnected)
59 }
60
61 async fn recv(&mut self) -> Result<ServerEvent, ClientError> {
62 LocalEnd::recv(self)
63 .await
64 .map_err(|_| ClientError::Disconnected)
65 }
66
67 async fn close(&mut self) {
68 LocalEnd::close(self);
69 }
70}
71
72impl ClientMessageTransport for LocalEnd<ClientCommand, ServerMessage> {
73 async fn send(&mut self, command: ClientCommand) -> Result<(), ClientError> {
74 LocalEnd::send(self, command)
75 .await
76 .map_err(|_| ClientError::Disconnected)
77 }
78
79 async fn recv(&mut self) -> Result<ServerMessage, ClientError> {
80 LocalEnd::recv(self)
81 .await
82 .map_err(|_| ClientError::Disconnected)
83 }
84
85 async fn close(&mut self) {
86 LocalEnd::close(self);
87 }
88}
89
90pub(crate) struct Decoded<T> {
91 transport: T,
92 cache: DocumentCache,
93}
94
95impl<T> Decoded<T> {
96 pub(crate) fn new(transport: T) -> Self {
97 Self {
98 transport,
99 cache: DocumentCache::default(),
100 }
101 }
102}
103
104impl<T: ClientMessageTransport> Transport for Decoded<T> {
105 async fn send(&mut self, command: ClientCommand) -> Result<(), ClientError> {
106 self.transport.send(command).await
107 }
108
109 async fn recv(&mut self) -> Result<ServerEvent, ClientError> {
110 let message = self.transport.recv().await?;
111 Ok(self.cache.apply_event(message)?)
112 }
113
114 async fn close(&mut self) {
115 self.transport.close().await;
116 }
117}
118
119#[cfg(feature = "websocket")]
120pub(crate) struct Reconnecting {
121 url: String,
122 headers: Vec<ConnectionHeader>,
123 socket: Decoded<ws::WebSocketTransport>,
124}
125
126#[cfg(feature = "websocket")]
127impl Reconnecting {
128 pub(crate) async fn connect(
129 url: &str,
130 headers: Vec<ConnectionHeader>,
131 ) -> Result<Self, ClientError> {
132 let socket = ws::WebSocketTransport::try_connect(url, &headers).await?;
133 Ok(Self {
134 url: url.to_owned(),
135 headers,
136 socket: Decoded::new(socket),
137 })
138 }
139}
140
141#[cfg(feature = "websocket")]
142impl Transport for Reconnecting {
143 async fn send(&mut self, command: ClientCommand) -> Result<(), ClientError> {
144 self.socket.send(command).await
145 }
146
147 async fn recv(&mut self) -> Result<ServerEvent, ClientError> {
148 self.socket.recv().await
149 }
150
151 async fn close(&mut self) {
152 self.socket.close().await;
153 }
154
155 fn reconnects(&self) -> bool {
156 true
157 }
158
159 async fn reconnect(&mut self) -> Result<(), ClientError> {
160 let socket = ws::WebSocketTransport::try_connect(&self.url, &self.headers).await?;
161 self.socket = Decoded::new(socket);
162 Ok(())
163 }
164}