1use std::{any::type_name, ops::Deref, sync::Arc};
2
3use actix_http::Extensions;
4use actix_utils::future::{err, ok, Ready};
5use futures_core::future::LocalBoxFuture;
6use serde::{de, Serialize};
7
8use crate::{dev::Payload, error, Error, FromRequest, HttpRequest};
9
10pub(crate) trait DataFactory {
12 fn create(&self, extensions: &mut Extensions) -> bool;
14}
15
16pub(crate) type FnDataFactory =
17 Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
18
19#[doc(alias = "state")]
89#[derive(Debug)]
90pub struct Data<T: ?Sized>(Arc<T>);
91
92impl<T> Data<T> {
93 pub fn new(state: T) -> Data<T> {
95 Data(Arc::new(state))
96 }
97}
98
99impl<T: ?Sized> Data<T> {
100 pub fn get_ref(&self) -> &T {
102 self.0.as_ref()
103 }
104
105 pub fn into_inner(self) -> Arc<T> {
107 self.0
108 }
109}
110
111impl<T: ?Sized> Deref for Data<T> {
112 type Target = Arc<T>;
113
114 fn deref(&self) -> &Arc<T> {
115 &self.0
116 }
117}
118
119impl<T: ?Sized> Clone for Data<T> {
120 fn clone(&self) -> Data<T> {
121 Data(Arc::clone(&self.0))
122 }
123}
124
125impl<T: ?Sized> From<Arc<T>> for Data<T> {
126 fn from(arc: Arc<T>) -> Self {
127 Data(arc)
128 }
129}
130
131impl<T: Default> Default for Data<T> {
132 fn default() -> Self {
133 Data::new(T::default())
134 }
135}
136
137impl<T> Serialize for Data<T>
138where
139 T: Serialize,
140{
141 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
142 where
143 S: serde::Serializer,
144 {
145 self.0.serialize(serializer)
146 }
147}
148impl<'de, T> de::Deserialize<'de> for Data<T>
149where
150 T: de::Deserialize<'de>,
151{
152 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153 where
154 D: de::Deserializer<'de>,
155 {
156 Ok(Data::new(T::deserialize(deserializer)?))
157 }
158}
159
160impl<T: ?Sized + 'static> FromRequest for Data<T> {
161 type Error = Error;
162 type Future = Ready<Result<Self, Error>>;
163
164 #[inline]
165 fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
166 if let Some(st) = req.app_data::<Data<T>>() {
167 ok(st.clone())
168 } else {
169 log::debug!(
170 "Failed to extract `Data<{}>` for `{}` handler. For the Data extractor to work \
171 correctly, wrap the data with `Data::new()` and pass it to `App::app_data()`. \
172 Ensure that types align in both the set and retrieve calls.",
173 type_name::<T>(),
174 req.match_name().unwrap_or_else(|| req.path())
175 );
176
177 err(error::ErrorInternalServerError(
178 "Requested application data is not configured correctly. \
179 View/enable debug logs for more details.",
180 ))
181 }
182 }
183}
184
185impl<T: ?Sized + 'static> DataFactory for Data<T> {
186 fn create(&self, extensions: &mut Extensions) -> bool {
187 extensions.insert(Data(Arc::clone(&self.0)));
188 true
189 }
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195 use crate::{
196 dev::Service,
197 http::StatusCode,
198 test::{init_service, TestRequest},
199 web, App, HttpResponse,
200 };
201
202 #[allow(deprecated)]
204 #[actix_rt::test]
205 async fn test_data_extractor() {
206 let srv = init_service(
207 App::new()
208 .data("TEST".to_string())
209 .service(web::resource("/").to(|data: web::Data<String>| {
210 assert_eq!(data.to_lowercase(), "test");
211 HttpResponse::Ok()
212 })),
213 )
214 .await;
215
216 let req = TestRequest::default().to_request();
217 let resp = srv.call(req).await.unwrap();
218 assert_eq!(resp.status(), StatusCode::OK);
219
220 let srv = init_service(
221 App::new()
222 .data(10u32)
223 .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
224 )
225 .await;
226 let req = TestRequest::default().to_request();
227 let resp = srv.call(req).await.unwrap();
228 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
229
230 let srv = init_service(
231 App::new()
232 .data(10u32)
233 .data(13u32)
234 .app_data(12u64)
235 .app_data(15u64)
236 .default_service(web::to(|n: web::Data<u32>, req: HttpRequest| {
237 assert_eq!(*req.app_data::<u64>().unwrap(), 15);
239 assert_eq!(*n.into_inner(), 13);
240 HttpResponse::Ok()
241 })),
242 )
243 .await;
244 let req = TestRequest::default().to_request();
245 let resp = srv.call(req).await.unwrap();
246 assert_eq!(resp.status(), StatusCode::OK);
247 }
248
249 #[actix_rt::test]
250 async fn test_app_data_extractor() {
251 let srv = init_service(
252 App::new()
253 .app_data(Data::new(10usize))
254 .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
255 )
256 .await;
257
258 let req = TestRequest::default().to_request();
259 let resp = srv.call(req).await.unwrap();
260 assert_eq!(resp.status(), StatusCode::OK);
261
262 let srv = init_service(
263 App::new()
264 .app_data(Data::new(10u32))
265 .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
266 )
267 .await;
268 let req = TestRequest::default().to_request();
269 let resp = srv.call(req).await.unwrap();
270 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
271 }
272
273 #[allow(deprecated)]
275 #[actix_rt::test]
276 async fn test_route_data_extractor() {
277 let srv = init_service(
278 App::new().service(
279 web::resource("/")
280 .data(10usize)
281 .route(web::get().to(|_data: web::Data<usize>| HttpResponse::Ok())),
282 ),
283 )
284 .await;
285
286 let req = TestRequest::default().to_request();
287 let resp = srv.call(req).await.unwrap();
288 assert_eq!(resp.status(), StatusCode::OK);
289
290 let srv = init_service(
292 App::new().service(
293 web::resource("/")
294 .data(10u32)
295 .route(web::get().to(|_: web::Data<usize>| HttpResponse::Ok())),
296 ),
297 )
298 .await;
299 let req = TestRequest::default().to_request();
300 let resp = srv.call(req).await.unwrap();
301 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
302 }
303
304 #[allow(deprecated)]
306 #[actix_rt::test]
307 async fn test_override_data() {
308 let srv = init_service(
309 App::new()
310 .data(1usize)
311 .service(web::resource("/").data(10usize).route(web::get().to(
312 |data: web::Data<usize>| {
313 assert_eq!(**data, 10);
314 HttpResponse::Ok()
315 },
316 ))),
317 )
318 .await;
319
320 let req = TestRequest::default().to_request();
321 let resp = srv.call(req).await.unwrap();
322 assert_eq!(resp.status(), StatusCode::OK);
323 }
324
325 #[actix_rt::test]
326 async fn test_data_from_arc() {
327 let data_new = Data::new(String::from("test-123"));
328 let data_from_arc = Data::from(Arc::new(String::from("test-123")));
329 assert_eq!(data_new.0, data_from_arc.0);
330 }
331
332 #[actix_rt::test]
333 async fn test_data_from_dyn_arc() {
334 trait TestTrait {
335 fn get_num(&self) -> i32;
336 }
337 struct A {}
338 impl TestTrait for A {
339 fn get_num(&self) -> i32 {
340 42
341 }
342 }
343 let dyn_arc_box: Arc<Box<dyn TestTrait>> = Arc::new(Box::new(A {}));
345 let data_arc_box = Data::from(dyn_arc_box);
346 let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
348 let data_arc = Data::from(dyn_arc);
349 assert_eq!(data_arc_box.get_num(), data_arc.get_num())
350 }
351
352 #[actix_rt::test]
353 async fn test_dyn_data_into_arc() {
354 trait TestTrait {
355 fn get_num(&self) -> i32;
356 }
357 struct A {}
358 impl TestTrait for A {
359 fn get_num(&self) -> i32 {
360 42
361 }
362 }
363 let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
364 let data_arc = Data::from(dyn_arc);
365 let arc_from_data = data_arc.clone().into_inner();
366 assert_eq!(data_arc.get_num(), arc_from_data.get_num())
367 }
368
369 #[actix_rt::test]
370 async fn test_get_ref_from_dyn_data() {
371 trait TestTrait {
372 fn get_num(&self) -> i32;
373 }
374 struct A {}
375 impl TestTrait for A {
376 fn get_num(&self) -> i32 {
377 42
378 }
379 }
380 let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
381 let data_arc = Data::from(dyn_arc);
382 let ref_data = data_arc.get_ref();
383 assert_eq!(data_arc.get_num(), ref_data.get_num())
384 }
385}