socketioxide/extract/
extensions.rs1use std::convert::Infallible;
2use std::sync::Arc;
3
4use crate::adapter::Adapter;
5use crate::handler::{FromConnectParts, FromDisconnectParts, FromMessageParts};
6use crate::socket::{DisconnectReason, Socket};
7use socketioxide_core::Value;
8
9#[cfg(feature = "extensions")]
10pub use extensions_extract::*;
11
12pub struct ExtensionNotFound<T>(std::marker::PhantomData<T>);
14
15impl<T> std::fmt::Display for ExtensionNotFound<T> {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 write!(
18 f,
19 "Extension of type {} not found, maybe you forgot to insert it in the extensions map?",
20 std::any::type_name::<T>()
21 )
22 }
23}
24impl<T> std::fmt::Debug for ExtensionNotFound<T> {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, "ExtensionNotFound {}", std::any::type_name::<T>())
27 }
28}
29impl<T> std::error::Error for ExtensionNotFound<T> {}
30
31fn extract_http_extension<T: Clone + Send + Sync + 'static>(
32 s: &Arc<Socket<impl Adapter>>,
33) -> Result<T, ExtensionNotFound<T>> {
34 s.req_parts()
35 .extensions
36 .get::<T>()
37 .cloned()
38 .ok_or(ExtensionNotFound(std::marker::PhantomData))
39}
40
41pub struct HttpExtension<T>(pub T);
43
44pub struct MaybeHttpExtension<T>(pub Option<T>);
46
47impl<A: Adapter, T: Clone + Send + Sync + 'static> FromConnectParts<A> for HttpExtension<T> {
48 type Error = ExtensionNotFound<T>;
49 fn from_connect_parts(
50 s: &Arc<Socket<A>>,
51 _: &Option<Value>,
52 ) -> Result<Self, ExtensionNotFound<T>> {
53 extract_http_extension(s).map(HttpExtension)
54 }
55}
56
57impl<A: Adapter, T: Clone + Send + Sync + 'static> FromConnectParts<A> for MaybeHttpExtension<T> {
58 type Error = Infallible;
59 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Infallible> {
60 Ok(MaybeHttpExtension(extract_http_extension(s).ok()))
61 }
62}
63
64impl<A: Adapter, T: Clone + Send + Sync + 'static> FromDisconnectParts<A> for HttpExtension<T> {
65 type Error = ExtensionNotFound<T>;
66 fn from_disconnect_parts(
67 s: &Arc<Socket<A>>,
68 _: DisconnectReason,
69 ) -> Result<Self, ExtensionNotFound<T>> {
70 extract_http_extension(s).map(HttpExtension)
71 }
72}
73impl<A: Adapter, T: Clone + Send + Sync + 'static> FromDisconnectParts<A>
74 for MaybeHttpExtension<T>
75{
76 type Error = Infallible;
77 fn from_disconnect_parts(s: &Arc<Socket<A>>, _: DisconnectReason) -> Result<Self, Infallible> {
78 Ok(MaybeHttpExtension(extract_http_extension(s).ok()))
79 }
80}
81
82impl<A: Adapter, T: Clone + Send + Sync + 'static> FromMessageParts<A> for HttpExtension<T> {
83 type Error = ExtensionNotFound<T>;
84 fn from_message_parts(
85 s: &Arc<Socket<A>>,
86 _: &mut Value,
87 _: &Option<i64>,
88 ) -> Result<Self, ExtensionNotFound<T>> {
89 extract_http_extension(s).map(HttpExtension)
90 }
91}
92impl<A: Adapter, T: Clone + Send + Sync + 'static> FromMessageParts<A> for MaybeHttpExtension<T> {
93 type Error = Infallible;
94 fn from_message_parts(
95 s: &Arc<Socket<A>>,
96 _: &mut Value,
97 _: &Option<i64>,
98 ) -> Result<Self, Infallible> {
99 Ok(MaybeHttpExtension(extract_http_extension(s).ok()))
100 }
101}
102
103super::__impl_deref!(HttpExtension);
104super::__impl_deref!(MaybeHttpExtension<T>: Option<T>);
105
106#[cfg(feature = "extensions")]
107mod extensions_extract {
108 use super::*;
109
110 fn extract_extension<T: Clone + Send + Sync + 'static>(
111 s: &Arc<Socket<impl Adapter>>,
112 ) -> Result<T, ExtensionNotFound<T>> {
113 s.extensions
114 .get::<T>()
115 .ok_or(ExtensionNotFound(std::marker::PhantomData))
116 }
117
118 pub struct Extension<T>(pub T);
124
125 pub struct MaybeExtension<T>(pub Option<T>);
127
128 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromConnectParts<A> for Extension<T> {
129 type Error = ExtensionNotFound<T>;
130 fn from_connect_parts(
131 s: &Arc<Socket<A>>,
132 _: &Option<Value>,
133 ) -> Result<Self, ExtensionNotFound<T>> {
134 extract_extension(s).map(Extension)
135 }
136 }
137 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromConnectParts<A> for MaybeExtension<T> {
138 type Error = Infallible;
139 fn from_connect_parts(s: &Arc<Socket<A>>, _: &Option<Value>) -> Result<Self, Infallible> {
140 Ok(MaybeExtension(extract_extension(s).ok()))
141 }
142 }
143 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromDisconnectParts<A> for Extension<T> {
144 type Error = ExtensionNotFound<T>;
145 fn from_disconnect_parts(
146 s: &Arc<Socket<A>>,
147 _: DisconnectReason,
148 ) -> Result<Self, ExtensionNotFound<T>> {
149 extract_extension(s).map(Extension)
150 }
151 }
152 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromDisconnectParts<A> for MaybeExtension<T> {
153 type Error = Infallible;
154 fn from_disconnect_parts(
155 s: &Arc<Socket<A>>,
156 _: DisconnectReason,
157 ) -> Result<Self, Infallible> {
158 Ok(MaybeExtension(extract_extension(s).ok()))
159 }
160 }
161 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromMessageParts<A> for Extension<T> {
162 type Error = ExtensionNotFound<T>;
163 fn from_message_parts(
164 s: &Arc<Socket<A>>,
165 _: &mut Value,
166 _: &Option<i64>,
167 ) -> Result<Self, ExtensionNotFound<T>> {
168 extract_extension(s).map(Extension)
169 }
170 }
171 impl<A: Adapter, T: Clone + Send + Sync + 'static> FromMessageParts<A> for MaybeExtension<T> {
172 type Error = Infallible;
173 fn from_message_parts(
174 s: &Arc<Socket<A>>,
175 _: &mut Value,
176 _: &Option<i64>,
177 ) -> Result<Self, Infallible> {
178 Ok(MaybeExtension(extract_extension(s).ok()))
179 }
180 }
181 super::super::__impl_deref!(Extension);
182 super::super::__impl_deref!(MaybeExtension<T>: Option<T>);
183}