Hi, having some lack of understanding on traits constraints
use std::future::Future;
use std::pin::Pin;
use tower::filter::{AsyncPredicate, AsyncFilterLayer};
use tower::{BoxError, Service, ServiceBuilder, ServiceExt};
#[derive(Debug, Clone)]
struct MyFilterPredicate { val: u32, }
impl AsyncPredicate<u32> for MyFilterPredicate {
type Future = Pin<Box<dyn Future<Output=Result<Self::Request, BoxError>>>>;
type Request = u32;
fn check(&mut self, request: u32) -> Self::Future {
Box::pin( async move { Ok(request) })
}
}
pub struct Builder<U> { predicate: U, }
impl<U> Builder<U>
{
pub fn new(predicate: U) -> Self { Self { predicate } }
pub fn build(&mut self ) -> impl Service<u32, Response=u32, Error=BoxError> + '_
where U: Clone + AsyncPredicate<u32>
{
// (A) - This compiles nicely
let filter_layer = AsyncFilterLayer::new( MyFilterPredicate{ val: 3});
// (B) - This will not compile and generates the errors below
let filter_layer = AsyncFilterLayer::new( self.predicate.clone() );
let mut svc = ServiceBuilder::new();
let mut svc = svc.layer(filter_layer);
let svc = svc.service_fn(dummy);
svc
}
}
async fn dummy(req: u32) -> Result<u32, BoxError> { Ok(req) }
error[E0631]: type mismatch in function arguments
--> src/tryfilter7.rs:30:33
|
30 | pub fn build(&mut self ) -> impl Service<u32, Response=Result<u32, BoxError>, Error=BoxError> + '_
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn(<U as AsyncPredicate<u32>>::Request) -> _`
...
44 | async fn dummy(req: u32) -> Result<u32, BoxError> {
| ------------------------------------------------- found signature of `fn(u32) -> _`
|
= note: required because of the requirements on the impl of `Service<<U as AsyncPredicate<u32>>::Request>` for `ServiceFn<fn(u32) -> impl std::future::Future {dummy}>`
= note: 1 redundant requirements hidden
= note: required because of the requirements on the impl of `Service<u32>` for `AsyncFilter<ServiceFn<fn(u32) -> impl std::future::Future {dummy}>, U>`
there are two variants of the filter_layer
-
(A) by directly constructing MyFilterPredicate and compiles nicely,
(B) uses the member of Builder (predicate: U) and doesn't compiles.
I think both should be equivalent, since in the fn build()
i added the trait constraints?
Obviously, i don't understand something or i am missing something. What is the difference and why does (B) not compile?