socketioxide/extract/
socket.rs

1use 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
14/// An Extractor that returns a reference to a [`Socket`].
15///
16/// It is generic over the [`Adapter`] type. If you plan to use it with another adapter than the default,
17/// make sure to have a handler that is [generic over the adapter type](crate#adapters).
18pub 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    /// Disconnect the socket from the current namespace,
71    ///
72    /// It will also call the disconnect handler if it is set.
73    #[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
84/// An Extractor to send an ack response corresponding to the current event.
85/// If the client sent a normal message without expecting an ack, the ack callback will do nothing.
86///
87/// It is generic over the [`Adapter`] type. If you plan to use it with another adapter than the default,
88/// make sure to have a handler that is [generic over the adapter type](crate#adapters).
89pub 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    /// Send the ack response to the client.
109    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}