tower-web icon indicating copy to clipboard operation
tower-web copied to clipboard

Implement Middleware for Either

Open shepmaster opened this issue 7 years ago • 5 comments

One usage in context:

let cors = if config.cors_enabled {
    let cors = CorsBuilder::new()
        .allow_origins(AllowedOrigins::Any { allow_null: true })
        .allow_headers(vec![header::CONTENT_TYPE])
        .allow_methods(vec![Method::GET, Method::POST])
        .allow_credentials(false)
        .max_age(Duration::from_secs(ONE_HOUR_IN_SECONDS as u64))
        .prefer_wildcard(true)
        .build();

    Either::A(cors)
} else {
    Either::B(Identity::new())
};

ServiceBuilder::new()
    .resource(Index::new(config.root.clone()))
    .resource(Assets::new(config.root))
    .resource(SandboxFixme)
    .resource(Meta::default())
    .resource(Gist::new(config.gh_token))
    .middleware(cors)
    .run(&addr).unwrap();

shepmaster avatar Aug 25 '18 16:08 shepmaster

Could even provide a helper thing:

let m = middleware::maybe(some_bool, || {
    // create middleware here
})

shepmaster avatar Aug 25 '18 16:08 shepmaster

a helper thing:

I say this, but as far as I can tell you either leak the type:

fn maybe<M>(enabled: bool, f: impl FnOnce() -> M) -> Either<M, Identity> {
    if enabled {
        Either::A(f())
    } else {
        Either::B(Identity::new())
    }
}

Or the trait bounds for impl trait are so complicated that I have not yet figured them out.

shepmaster avatar Aug 25 '18 16:08 shepmaster

I can merge this now but sooner then later, Middleware will be moved into a dedicated crate and at which point you will no longer be able to impl Middleware for either due to coherence.

Either way, this solution also isn’t fully generic to all Middleware (only http) so that means there is still a problem...

carllerche avatar Aug 28 '18 04:08 carllerche

Middleware will be moved into a dedicated crate

tower-web requires M: HttpMiddleware; so this tailored for that case. Do you expect this new crate to be beyond tower-web? Will there be a http-middleware specific crate if so?

Would you prefer there to be a custom EitherHttpMiddleware type?

shepmaster avatar Aug 28 '18 15:08 shepmaster

I expect that there will be tower-http for all the http specific things.

I wonder if we could have an IntoEither trait for “joining” the response type from two either branches. The problem would then be where does the implementation for http::Response live. On Tue, Aug 28, 2018 at 8:57 AM Jake Goulding [email protected] wrote:

Middleware will be moved into a dedicated crate

tower-web requires M: HttpMiddleware; so this tailored for that case. Do you expect this new crate to be beyond tower-web? Will there be a http-middleware specific crate if so?

Would you prefer there to be a custom EitherHttpMiddleware type?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/carllerche/tower-web/pull/81#issuecomment-416640304, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAYJOYFOLR-SoNYWhn83SHtXtFfAy17ks5uVWhpgaJpZM4WMcEI .

carllerche avatar Aug 28 '18 18:08 carllerche