socketioxide/extract/
socket.rs1use std::convert::Infallible;
2use std::fmt;
3use std::sync::Arc;
4
5use crate::{
6 SendError, SocketError, SocketIo,
7 adapter::{Adapter, LocalAdapter},
8 handler::{FromConnectParts, FromDisconnectParts, FromMessageParts},
9 socket::{DisconnectReason, Socket},
10};
11use serde::Serialize;
12use socketioxide_core::{Value, packet::Packet, parser::Parse};
13
14pub struct SocketRef<A: Adapter = LocalAdapter>(Arc<Socket<A>>);
19
20impl<A: Adapter> FromConnectParts<A> for SocketRef<A> {
21 type Error = Infallible;
22 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Infallible> {
23 Ok(SocketRef(s.clone()))
24 }
25}
26impl<A: Adapter> FromMessageParts<A> for SocketRef<A> {
27 type Error = Infallible;
28 fn from_message_parts(
29 s: &Arc<Socket<A>>,
30 _: &mut Value,
31 _: &Option<i64>,
32 ) -> Result<Self, Infallible> {
33 Ok(SocketRef(s.clone()))
34 }
35}
36impl<A: Adapter> FromDisconnectParts<A> for SocketRef<A> {
37 type Error = Infallible;
38 fn from_disconnect_parts(s: &Arc<Socket<A>>, _: DisconnectReason) -> Result<Self, Infallible> {
39 Ok(SocketRef(s.clone()))
40 }
41}
42
43impl<A: Adapter> std::ops::Deref for SocketRef<A> {
44 type Target = Socket<A>;
45 #[inline(always)]
46 fn deref(&self) -> &Self::Target {
47 &self.0
48 }
49}
50impl<A: Adapter> PartialEq for SocketRef<A> {
51 #[inline(always)]
52 fn eq(&self, other: &Self) -> bool {
53 self.0.id == other.0.id
54 }
55}
56impl<A: Adapter> From<Arc<Socket<A>>> for SocketRef<A> {
57 #[inline(always)]
58 fn from(socket: Arc<Socket<A>>) -> Self {
59 Self(socket)
60 }
61}
62
63impl<A: Adapter> Clone for SocketRef<A> {
64 fn clone(&self) -> Self {
65 Self(self.0.clone())
66 }
67}
68
69impl<A: Adapter> SocketRef<A> {
70 #[inline(always)]
74 pub fn disconnect(self) -> Result<(), SocketError> {
75 self.0.disconnect()
76 }
77}
78impl<A: Adapter> fmt::Debug for SocketRef<A> {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 fmt::Debug::fmt(&self.0, f)
81 }
82}
83
84pub struct AckSender<A: Adapter = LocalAdapter> {
90 socket: Arc<Socket<A>>,
91 ack_id: Option<i64>,
92}
93impl<A: Adapter> FromMessageParts<A> for AckSender<A> {
94 type Error = Infallible;
95 fn from_message_parts(
96 s: &Arc<Socket<A>>,
97 _: &mut Value,
98 ack_id: &Option<i64>,
99 ) -> Result<Self, Infallible> {
100 Ok(Self::new(s.clone(), *ack_id))
101 }
102}
103impl<A: Adapter> AckSender<A> {
104 pub(crate) fn new(socket: Arc<Socket<A>>, ack_id: Option<i64>) -> Self {
105 Self { socket, ack_id }
106 }
107
108 pub fn send<T: Serialize + ?Sized>(self, data: &T) -> Result<(), SendError> {
110 use crate::socket::PermitExt;
111 if let Some(ack_id) = self.ack_id {
112 let permit = match self.socket.reserve() {
113 Ok(permit) => permit,
114 Err(e) => {
115 #[cfg(feature = "tracing")]
116 tracing::debug!("sending error during emit message: {e:?}");
117 return Err(SendError::Socket(e));
118 }
119 };
120 let ns = self.socket.ns.path.clone();
121 let data = self.socket.parser.encode_value(data, None)?;
122 let packet = Packet::ack(ns, data, ack_id);
123 permit.send(packet, self.socket.parser);
124 Ok(())
125 } else {
126 Ok(())
127 }
128 }
129}
130
131impl<A: Adapter> FromConnectParts<A> for crate::ProtocolVersion {
132 type Error = Infallible;
133 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Infallible> {
134 Ok(s.protocol())
135 }
136}
137impl<A: Adapter> FromMessageParts<A> for crate::ProtocolVersion {
138 type Error = Infallible;
139 fn from_message_parts(
140 s: &Arc<Socket<A>>,
141 _: &mut Value,
142 _: &Option<i64>,
143 ) -> Result<Self, Infallible> {
144 Ok(s.protocol())
145 }
146}
147impl<A: Adapter> FromDisconnectParts<A> for crate::ProtocolVersion {
148 type Error = Infallible;
149 fn from_disconnect_parts(s: &Arc<Socket<A>>, _: DisconnectReason) -> Result<Self, Infallible> {
150 Ok(s.protocol())
151 }
152}
153
154impl<A: Adapter> FromConnectParts<A> for crate::TransportType {
155 type Error = Infallible;
156 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Infallible> {
157 Ok(s.transport_type())
158 }
159}
160impl<A: Adapter> FromMessageParts<A> for crate::TransportType {
161 type Error = Infallible;
162 fn from_message_parts(
163 s: &Arc<Socket<A>>,
164 _: &mut Value,
165 _: &Option<i64>,
166 ) -> Result<Self, Infallible> {
167 Ok(s.transport_type())
168 }
169}
170impl<A: Adapter> FromDisconnectParts<A> for crate::TransportType {
171 type Error = Infallible;
172 fn from_disconnect_parts(s: &Arc<Socket<A>>, _: DisconnectReason) -> Result<Self, Infallible> {
173 Ok(s.transport_type())
174 }
175}
176
177impl<A: Adapter> FromDisconnectParts<A> for DisconnectReason {
178 type Error = Infallible;
179 fn from_disconnect_parts(
180 _: &Arc<Socket<A>>,
181 reason: DisconnectReason,
182 ) -> Result<Self, Infallible> {
183 Ok(reason)
184 }
185}
186
187impl<A: Adapter> FromConnectParts<A> for SocketIo<A> {
188 type Error = Infallible;
189
190 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Self::Error> {
191 Ok(s.get_io().clone())
192 }
193}
194impl<A: Adapter> FromMessageParts<A> for SocketIo<A> {
195 type Error = Infallible;
196
197 fn from_message_parts(
198 s: &Arc<Socket<A>>,
199 _: &mut Value,
200 _: &Option<i64>,
201 ) -> Result<Self, Self::Error> {
202 Ok(s.get_io().clone())
203 }
204}
205impl<A: Adapter> FromDisconnectParts<A> for SocketIo<A> {
206 type Error = Infallible;
207
208 fn from_disconnect_parts(s: &Arc<Socket<A>>, _: DisconnectReason) -> Result<Self, Self::Error> {
209 Ok(s.get_io().clone())
210 }
211}