scratch_cloud_server/
lib.rs

1use futures_util::SinkExt;
2use futures_util::StreamExt;
3use tokio::net::TcpStream;
4use tokio_tungstenite::tungstenite::Message as WSMessage;
5
6pub mod messages;
7
8use messages::*;
9
10#[derive(Debug)]
11pub enum Error {
12    ExpectedTextMsg,
13    JSONError(serde_json::Error),
14    WSError(tokio_tungstenite::tungstenite::Error),
15}
16impl From<serde_json::Error> for Error {
17    fn from(value: serde_json::Error) -> Self {
18        Self::JSONError(value)
19    }
20}
21impl From<tokio_tungstenite::tungstenite::Error> for Error {
22    fn from(value: tokio_tungstenite::tungstenite::Error) -> Self {
23        Self::WSError(value)
24    }
25}
26
27pub struct CloudServerStream {
28    write:
29        futures_util::stream::SplitSink<tokio_tungstenite::WebSocketStream<TcpStream>, WSMessage>,
30    read: futures_util::stream::SplitStream<tokio_tungstenite::WebSocketStream<TcpStream>>,
31}
32impl CloudServerStream {
33    pub async fn from_tcp_stream(stream: TcpStream) -> Result<Self, Error> {
34        let ws_stream = tokio_tungstenite::accept_async(stream).await?;
35        let (write, read) = ws_stream.split();
36
37        Ok(Self { write, read })
38    }
39
40    pub async fn recv(&mut self) -> Result<Option<ServerboundMessage>, Error> {
41        let msg = match self.read.next().await {
42            Some(msg) => match msg? {
43                WSMessage::Text(msg) => msg.to_string(),
44                WSMessage::Close(msg) => {
45                    match msg {
46                        Some(msg) => println!("Closed with frame: {}", msg),
47                        None => {}
48                    }
49                    return Ok(None);
50                }
51                _ => {
52                    return Err(Error::ExpectedTextMsg);
53                }
54            },
55            None => {
56                return Ok(None);
57            }
58        };
59        Ok(Some(serde_json::from_str(&msg)?))
60    }
61
62    pub async fn send(&mut self, msg: ClientboundMessage) -> Result<(), Error> {
63        let value = serde_json::to_string(&msg)?;
64        self.write.send(WSMessage::Text(value.into())).await?;
65        Ok(())
66    }
67}