diff --git a/CHANGES.md b/CHANGES.md index 3419ce818..86e022409 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ * Add `TrailingSlash::MergeOnly` behaviour to `NormalizePath`, which allow `NormalizePath` to keep the trailing slash's existance as it is. [#1695] * Fix `ResourceMap` recursive references when printing/debugging. [#1708] +* Remove bound `std::marker::Sized` from `web::Data` to support storing `Arc` via `web::Data::from` [#1710] [#1708]: https://github.com/actix/actix-web/pull/1708 diff --git a/src/data.rs b/src/data.rs index c50b30328..6405fd901 100644 --- a/src/data.rs +++ b/src/data.rs @@ -66,7 +66,7 @@ pub(crate) type FnDataFactory = /// } /// ``` #[derive(Debug)] -pub struct Data(Arc); +pub struct Data(Arc); impl Data { /// Create new `Data` instance. @@ -89,7 +89,7 @@ impl Data { } } -impl Deref for Data { +impl Deref for Data { type Target = Arc; fn deref(&self) -> &Arc { @@ -97,19 +97,19 @@ impl Deref for Data { } } -impl Clone for Data { +impl Clone for Data { fn clone(&self) -> Data { Data(self.0.clone()) } } -impl From> for Data { +impl From> for Data { fn from(arc: Arc) -> Self { Data(arc) } } -impl FromRequest for Data { +impl FromRequest for Data { type Config = (); type Error = Error; type Future = Ready>; @@ -131,7 +131,7 @@ impl FromRequest for Data { } } -impl DataFactory for Data { +impl DataFactory for Data { fn create(&self, extensions: &mut Extensions) -> bool { if !extensions.contains::>() { extensions.insert(Data(self.0.clone())); @@ -293,4 +293,24 @@ mod tests { let data_from_arc = Data::from(Arc::new(String::from("test-123"))); assert_eq!(data_new.0, data_from_arc.0) } + + #[actix_rt::test] + async fn test_data_from_dyn_arc() { + trait TestTrait { + fn get_num(&self) -> i32; + } + struct A {} + impl TestTrait for A { + fn get_num(&self) -> i32 { + 42 + } + } + // This works when Sized is required + let dyn_arc_box: Arc> = Arc::new(Box::new(A {})); + let data_arc_box = Data::from(dyn_arc_box); + // This works when Data Sized Bound is removed + let dyn_arc: Arc = Arc::new(A {}); + let data_arc = Data::from(dyn_arc); + assert_eq!(data_arc_box.get_num(), data_arc.get_num()) + } }