graphql_ws_client/next/
connection.rs1use std::future::Future;
2use std::pin::Pin;
3
4use crate::Error;
5
6pub trait Connection {
12 fn receive(&mut self) -> impl Future<Output = Option<Message>> + Send;
14
15 fn send(&mut self, message: Message) -> impl Future<Output = Result<(), Error>> + Send;
17}
18
19pub enum Message {
24 Text(String),
26 Close {
28 code: Option<u16>,
30 reason: Option<String>,
32 },
33 Ping,
35 Pong,
37}
38
39impl Message {
40 pub(crate) fn deserialize<T>(self) -> Result<T, Error>
41 where
42 T: serde::de::DeserializeOwned,
43 {
44 let Message::Text(text) = self else {
45 panic!("Don't call deserialize on non-text messages");
46 };
47
48 serde_json::from_str(&text).map_err(|error| Error::Decode(error.to_string()))
49 }
50
51 pub(crate) fn init(payload: Option<serde_json::Value>) -> Self {
52 Self::Text(
53 serde_json::to_string(&crate::protocol::ConnectionInit::new(payload))
54 .expect("payload is already serialized so this shouldn't fail"),
55 )
56 }
57
58 pub(crate) fn graphql_pong() -> Self {
59 Self::Text(serde_json::to_string(&crate::protocol::Message::Pong::<()>).unwrap())
60 }
61
62 pub(crate) fn graphql_ping() -> Self {
63 Self::Text(serde_json::to_string(&crate::protocol::Message::Ping::<()>).unwrap())
64 }
65
66 pub(crate) fn complete(id: usize) -> Self {
67 Self::Text(
68 serde_json::to_string(&crate::protocol::Message::Complete::<()> { id: id.to_string() })
69 .unwrap(),
70 )
71 }
72}
73
74pub(crate) trait ObjectSafeConnection: Send {
77 fn receive(&mut self) -> Pin<Box<dyn Future<Output = Option<Message>> + Send + '_>>;
78
79 fn send(
80 &mut self,
81 message: Message,
82 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + '_>>;
83}
84
85impl<T: Connection + Sized + Send> ObjectSafeConnection for T {
86 fn receive(&mut self) -> Pin<Box<dyn Future<Output = Option<Message>> + Send + '_>> {
87 Box::pin(Connection::receive(self))
88 }
89
90 fn send(
91 &mut self,
92 message: Message,
93 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + '_>> {
94 Box::pin(Connection::send(self, message))
95 }
96}