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