Function tower::layer::layer_fn

source ·
pub fn layer_fn<T>(f: T) -> LayerFn<T>
Expand description

Returns a new LayerFn that implements Layer by calling the given function.

The Layer::layer method takes a type implementing Service and returns a different type implementing Service. In many cases, this can be implemented by a function or a closure. The LayerFn helper allows writing simple Layer implementations without needing the boilerplate of a new struct implementing Layer.

Example

// A middleware that logs requests before forwarding them to another service
pub struct LogService<S> {
    target: &'static str,
    service: S,
}

impl<S, Request> Service<Request> for LogService<S>
where
    S: Service<Request>,
    Request: fmt::Debug,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = S::Future;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.service.poll_ready(cx)
    }

    fn call(&mut self, request: Request) -> Self::Future {
        // Log the request
        println!("request = {:?}, target = {:?}", request, self.target);

        self.service.call(request)
    }
}

// A `Layer` that wraps services in `LogService`
let log_layer = layer_fn(|service| {
    LogService {
        service,
        target: "tower-docs",
    }
});

// An example service. This one uppercases strings
let uppercase_service = tower::service_fn(|request: String| async move {
    Ok::<_, Infallible>(request.to_uppercase())
});

// Wrap our service in a `LogService` so requests are logged.
let wrapped_service = log_layer.layer(uppercase_service);