I have the following implementation of the actix_web FromRequest
trait:
impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
type Error = ::actix_web::Error;
type Future =
::futures::future::MapOk<::futures::future::Ready<Result<Self, Self::Error>>, ???>;
type Config = ();
fn from_request(
req: &::actix_web::HttpRequest,
payload: &mut actix_web::dev::Payload,
) -> Self::Future {
RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
}
}
As the return type is an FnOnce
, I cannot figure out how to actually set the return type. According to the error message it should be FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>
, however that tells me that fnOnce
is not valid because it's not a known size at compile time.
RealSessionRepository::from_request
returns a future, also being an implementation of the FromRequest
trait.
Inserting the FnOnce definition like this:
impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
type Error = ::actix_web::Error;
type Future = ::futures::future::MapOk<
::futures::future::Ready<Result<Self, Self::Error>>,
FnOnce(RealSessionRepository) -> Box<(dyn SessionRepository + 'static)>,
>;
type Config = ();
fn from_request(
req: &::actix_web::HttpRequest,
payload: &mut actix_web::dev::Payload,
) -> Self::Future {
RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
}
}
gives the following set of error messages:
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:32:6
|
32 | impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `core::future::future::Future` for `futures_util::future::try_future::map_ok::MapOk<futures_util::future::ready::Ready<std::result::Result<std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>, actix_web::Error>>, (dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)>`
error[E0277]: expected a `std::ops::FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` closure, found `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
--> api-server\src\db\sessions.rs:32:6
|
32 | impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` closure, found `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
|
= help: the trait `std::ops::FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: required because of the requirements on the impl of `core::future::future::Future` for `futures_util::future::try_future::map_ok::MapOk<futures_util::future::ready::Ready<std::result::Result<std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>, actix_web::Error>>, (dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)>`
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:34:5
|
34 | / type Future = ::futures::future::MapOk<
35 | | ::futures::future::Ready<Result<Self, Self::Error>>,
36 | | FnOnce(RealSessionRepository) -> Box<(dyn SessionRepository + 'static)>,
37 | | >;
| |______^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `futures_util::future::try_future::map_ok::MapOk`
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:40:5
|
40 | / fn from_request(
41 | | req: &::actix_web::HttpRequest,
42 | | payload: &mut actix_web::dev::Payload,
43 | | ) -> Self::Future {
44 | | RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
45 | | }
| |_____^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `futures_util::future::try_future::map_ok::MapOk`
MRE is available at: https://github.com/zlepper/actix_web_mre since it requires actix, which is not available on the rust playground.
This is specially about how to handle this when i want a dynamic trait reference, in an associated type, which I do not own, and thus can't do a lot about changing. More specifically, how would i do it with an FnOnce, where the actual implementation is only generated at compile time (I would think).
I know I can shorten the type definitions slightly so they are not fully qualified, however this is something I would like to generate using a macro, so as far as I know it is better to use the full types.
Is there a better way to type out the return future? The current definition is quite hairy..