Closed
Description
I am writing some web server using axum library where I use multiple traits and put them in request extensions by converting them to Arc so that I don't have to make every handler accept generic parameters. Unfortunately I can't do that for SessionStore (which I use in a middleware for checking authentication) since it requires implementor to also implement Clone, making it non object safe. Is there a possibility to remove Clone requirement in next major version?
Example with handlers accepting generic parameters:
fn configure<U, T, S>(user_service: U, transaction_service: T, session_store: S) -> Router
where
U: UserService,
T: TransactionService ,
S: SessionStore
{
Router::new()
.route("/", handlers::index::<U>)
.route("/user", handlers::user::overview::<U, T, S>)
.layer(Extension(user_service))
.layer(Extension(transaction_service))
.layer(Extension(session_store))
}
// in handlers/index.rs
async fn index<U: UserService>(Extension(service): Extension<U>) -> impl IntoResponse {
//some stuff
}
// in handlers/user.rs
async fn overview<U: UserService, T: TransactionService, S: SessionStore>(
Extension(user_service): Extension<U>,
Extension(transaction_service): Extension<T>,
Extension(session_store): Extension<S>,
) -> impl IntoResponse {
//some stuff
}
And new way which I would be able to do if SessionStore is object safe:
fn configure<U, T, S>(user_service: U, transaction_service: T, session_store: S) -> Router
where
U: UserService,
T: TransactionService ,
S: SessionStore
{
Router::new()
.route("/", handlers::index)
.route("/user", handlers::user::overview)
.layer(Extension(Arc::new(user_service) as Arc<dyn UserService>))
.layer(Extension(Arc::new(transaction_service) as Arc<dyn TransactionService>))
.layer(Extension(Arc::new(session_store) as Arc<dyn SessionStore>)) // Not object safe, this will fail
}
// in handlers/index.rs
async fn index(Extension(service): Extension<Arc<dyn UserService>>) -> impl IntoResponse {
//some stuff
}
// in handlers/user.rs
async fn overview(
Extension(user_service): Extension<Arc<dyn UserService>>,
Extension(transaction_service): Extension<Arc<dyn TransactionService>>,
Extension(session_store): Extension<Arc<dyn SessionStore>>,
) -> impl IntoResponse {
//some stuff
}
This will make function signature smaller when I start adding more traits.