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
Add util::option_layer
and ServiceBuilder::option_layer
#555
Conversation
Thanks 👍 Should probably also be mentioned in the changelog. |
@@ -938,3 +940,12 @@ pub trait ServiceExt<Request>: tower_service::Service<Request> { | |||
} | |||
|
|||
impl<T: ?Sized, Request> ServiceExt<Request> for T where T: tower_service::Service<Request> {} | |||
|
|||
/// Convert an `Option<Layer>` into a `Layer` | |||
pub fn option_layer<L>(layer: Option<L>) -> Either<L, Identity> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to having a special wrapper function would be to just add an impl<L: Layer> for Option<L>
. That might have slightly nicer API ergonomics, since all Option<Layer>
s just are layers, rather than having to wrap them in option_layer
calls.
But, the downside to that is that this would have to be implemented in the tower_layer
crate, rather than in tower
. This means that we couldn't use Either
, which is defined in tower
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually like that option_layer
is explicit about whats happening. When looking at large layer stack being built with ServiceBuilder
it might be obvious which layers are optional and which aren't. Is this TimeoutLayer
applied all the time or only sometimes? Would have to check the type.
That combined with the annoyances of having to copy+paste Either
(or depend on the either crate) makes me think this approach is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidpdrsn Yeah, I think that makes sense. I'm also in favor of avoiding tower-service
changes when they're not absolutely necessary. We can always add an impl in tower-service
later if we end up deciding that is a good idea...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for API consistency's sake, WDYT about adding an option_service
(or something) that takes an Option<T: Service>
and returns an Optional<T>
? That way, we'd have option_layer
and option_service
functions.
I'd add that in a separate PR, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that sounds good.
63c95af
to
741eb1f
Compare
util::option_layer
and ServiceBuilder::option_layer
Thanks for reviewing. Added minimal examples with |
9ef34ed
to
9d523bc
Compare
9d523bc
to
4fc5947
Compare
Fixed doctests. Sorry for the noise. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some minor nits about the examples. Other than that, this change looks great and I'll happily merge it once the docs feedback is addressed.
Thanks for working on this @kazk!
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great, thanks again!
Closes #553