#Constraining Generics for Traits

8 messages · Page 1 of 1 (latest)

jade grotto
#
struct GovernorLayer;

impl<K, M, S> Layer<S> for GovernorLayer
where
    K: KeyExtractor,
    M: RateLimitingMiddleware<QuantaInstant>,
{
    type Service = Governor<K, M, S>;

    fn layer(&self, inner: S, config: &GovernorConfig<K, M>) -> Self::Service {
        Service::new(inner, config)
    }
}

Trying to implement a layer for Axum on the middleware, but I'm getting an interesting error:

the type parameter `M` is not constrained by the impl trait, self type, or predicates
unconstrained type parameter

I get the same error for K. What am I missing ? How do I constrain K and M?

wet forge
#

type parameters of impl blocks must either appear in the implementing type (GovernorLayer), the implemented trait (Layer<S>), or be bound in an associated type of another trait.

#

so you have a couple options. either make K and M type params of GovernorLayer, make them used in Layer, or make them specific to the layer function (fn layer<K, M>(...) -> ...).

jade grotto
#

OK, I tried it like so:

struct GovernorLayer;

impl<S> Layer<S> for GovernorLayer {
    fn layer<K, M>(&self, inner: S, config: &GovernorConfig<K, M>) -> Governor<K, M, S> {
        Service::new(inner, config)
    }
}

But K & M have constraints set by GovernorConfig that are not met

the trait bound `K: key_extractor::KeyExtractor` is not satisfied
the trait `key_extractor::KeyExtractor` is not implemented for `K`
#

I do not think I can change the generics from Layer, which is defined in tower, so I guess that just leaves adding them to Governor Layer

wet forge
jade grotto
#

I don't think I can, because layer is defined in a different crate

method `layer` has 2 type parameters but its trait declaration has 0 type parametersrustcE0049
wet forge
#

ah, then yeah you probably need GovernorLayer to have them as a PhantomData or whatnot