Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Option<F> a filter when F is a filter #1060

Open
futursolo opened this issue Aug 2, 2023 · 0 comments
Open

Make Option<F> a filter when F is a filter #1060

futursolo opened this issue Aug 2, 2023 · 0 comments
Labels
feature New feature or request

Comments

@futursolo
Copy link

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

I wish to make a route / filter that is enabled based on command line argument.
However, I find it is kind of cumbersome to have a filter optionally enabled.

I can currently find 3 solutions:

  1. boxing filter and assigning to variable
let mut f = base_filter().boxed();

// invoked with --with-extra-feature
if args.with_extra_feature {
    f = f.or(extra_filter()).unify().boxed();
}

f = f.or(other_filters());

However, this requires coercing filter to the same exact type, which means calling .unify().boxed() after every or() call and all filters needs to call into_response() manually to convert to a Response.

  1. use reject() when this filter is not needed.
base_filter()
    .or(
        if args.with_extra_feature {
            extra_filter().boxed()
        } else {
            reject_as_response().boxed()
        }
    )

However, this still requires me to make a custom reject filter that returns a Extract = Response.

  1. check with_extra_feature at each request

I would like to avoid this option as it is only determined by a factor that does not change after the program starts.

Describe the solution you'd like
A clear and concise description of what you want to happen.

If we make Option<F> where F: Filter implement Filter, where None always reject.

Then the above can be simplified to:

let f = base_filter()
    .or(args.with_extra_feature.then(extra_filter))
    .or(other_filters());

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

  1. or_maybe

Implements a method like or, but accepts an Option<F> where None ignores the filter (rejects?).

let f = base_filter()
    .or_maybe(args.with_extra_feature.then(extra_filter))
    .or(other_filters());
  1. Either<L, R>

Similar to futures::future::Either, but accepts 2 filters instead.

let f = base_filter();

let f = if args.with_extra_feature { f.or(extra_filter()).left() } else { f.right() };

Additional context
Add any other context or screenshots about the feature request here.

N/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant