Skip to content

Commit

Permalink
Remove Sized Bound for web::Data (actix#1712)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterUlb authored Sep 29, 2020
1 parent b4e02fe commit b5812b1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<dyn Trait>` via `web::Data::from` [#1710]

[#1708]: https://github.com/actix/actix-web/pull/1708

Expand Down
32 changes: 26 additions & 6 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub(crate) type FnDataFactory =
/// }
/// ```
#[derive(Debug)]
pub struct Data<T>(Arc<T>);
pub struct Data<T: ?Sized>(Arc<T>);

impl<T> Data<T> {
/// Create new `Data` instance.
Expand All @@ -89,27 +89,27 @@ impl<T> Data<T> {
}
}

impl<T> Deref for Data<T> {
impl<T: ?Sized> Deref for Data<T> {
type Target = Arc<T>;

fn deref(&self) -> &Arc<T> {
&self.0
}
}

impl<T> Clone for Data<T> {
impl<T: ?Sized> Clone for Data<T> {
fn clone(&self) -> Data<T> {
Data(self.0.clone())
}
}

impl<T> From<Arc<T>> for Data<T> {
impl<T: ?Sized> From<Arc<T>> for Data<T> {
fn from(arc: Arc<T>) -> Self {
Data(arc)
}
}

impl<T: 'static> FromRequest for Data<T> {
impl<T: ?Sized + 'static> FromRequest for Data<T> {
type Config = ();
type Error = Error;
type Future = Ready<Result<Self, Error>>;
Expand All @@ -131,7 +131,7 @@ impl<T: 'static> FromRequest for Data<T> {
}
}

impl<T: 'static> DataFactory for Data<T> {
impl<T: ?Sized + 'static> DataFactory for Data<T> {
fn create(&self, extensions: &mut Extensions) -> bool {
if !extensions.contains::<Data<T>>() {
extensions.insert(Data(self.0.clone()));
Expand Down Expand Up @@ -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<Box<dyn TestTrait>> = 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<dyn TestTrait> = Arc::new(A {});
let data_arc = Data::from(dyn_arc);
assert_eq!(data_arc_box.get_num(), data_arc.get_num())
}
}

0 comments on commit b5812b1

Please sign in to comment.