Trait ServiceExt

Source
pub trait ServiceExt<Req>: Service<Req> {
    // Provided methods
    fn with<T, R>(self, middleware: T) -> T::Service
       where Self: Sized,
             T: Middleware<Self>,
             T::Service: Service<R> { ... }
    fn then<F, Fut, Res, Err>(self, f: F) -> Then<Self, F>
       where Self: Sized,
             F: Fn(Result<Self::Response, Self::Error>) -> Fut + Send + Sync,
             Fut: Future<Output = Result<Res, Err>> + Send { ... }
    fn and_then<F, Fut, Res>(self, f: F) -> AndThen<Self, F>
       where Self: Sized,
             F: Fn(Self::Response) -> Fut + Send + Sync,
             Fut: Future<Output = Result<Res, Self::Error>> + Send { ... }
    fn or_else<F, Fut, Err>(self, f: F) -> OrElse<Self, F>
       where Self: Sized,
             F: Fn(Self::Error) -> Fut + Send + Sync,
             Fut: Future<Output = Result<Self::Response, Err>> + Send { ... }
    fn map_result<F, Res, Err>(self, f: F) -> MapResult<Self, F>
       where Self: Sized,
             F: Fn(Result<Self::Response, Self::Error>) -> Result<Res, Err> + Send + Sync { ... }
    fn map_response<F, Res>(self, f: F) -> MapResponse<Self, F>
       where Self: Sized,
             F: Fn(Self::Response) -> Res + Send + Sync { ... }
    fn map_err<F, Err>(self, f: F) -> MapErr<Self, F>
       where Self: Sized,
             F: Fn(Self::Error) -> Err + Send + Sync { ... }
    fn map_request<F, R>(self, f: F) -> MapRequest<Self, F>
       where Self: Sized,
             F: Fn(R) -> Req + Send + Sync { ... }
    fn boxed(self) -> BoxService<Req, Self::Response, Self::Error>
       where Self: Sized + 'static { ... }
    fn boxed_clone(self) -> BoxCloneService<Req, Self::Response, Self::Error>
       where Self: Sized + Clone + 'static { ... }
    fn boxed_arc(self) -> ArcService<Req, Self::Response, Self::Error>
       where Self: Sized + 'static { ... }
}
Expand description

Service 的扩展特征,提供了一些方便的功能。

Provided Methods§

Source

fn with<T, R>(self, middleware: T) -> T::Service
where Self: Sized, T: Middleware<Self>, T::Service: Service<R>,

在此服务上应用中间件。

§例子
use boluo_core::handler::handler_fn;
use boluo_core::middleware::middleware_fn;
use boluo_core::request::Request;
use boluo_core::service::{Service, ServiceExt};

fn add_extension<S>(service: S) -> impl Service<Request>
where
    S: Service<Request>,
{
    service.map_request(|mut req: Request| {
        req.extensions_mut().insert("My Extension");
        req
    })
}

let service = handler_fn(|| async {});
let service = service.with(middleware_fn(add_extension));
Source

fn then<F, Fut, Res, Err>(self, f: F) -> Then<Self, F>
where Self: Sized, F: Fn(Result<Self::Response, Self::Error>) -> Fut + Send + Sync, Fut: Future<Output = Result<Res, Err>> + Send,

在此服务执行完成后执行给定的异步函数。

§例子
use boluo_core::service::{service_fn, ServiceExt};

#[derive(Debug)]
struct MyError;

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "some error message")
    }
}

impl std::error::Error for MyError {}

async fn throw_error(_: ()) -> Result<(), MyError> {
    Err(MyError)
}

let service = service_fn(throw_error);
let service = service.then(|result| async move {
    if let Err(err) = &result {
        // 打印错误信息。
        println!("{err}");
    }
    result
});
Source

fn and_then<F, Fut, Res>(self, f: F) -> AndThen<Self, F>
where Self: Sized, F: Fn(Self::Response) -> Fut + Send + Sync, Fut: Future<Output = Result<Res, Self::Error>> + Send,

在此服务执行成功后执行给定的异步函数。

§例子
use boluo_core::body::Body;
use boluo_core::handler::handler_fn;
use boluo_core::service::ServiceExt;
use boluo_core::BoxError;

async fn hello() -> &'static str {
    "Hello, World!"
}

let service = handler_fn(hello);
let service = service.and_then(|response| async move {
    // 清空响应主体。
    Ok::<_, BoxError>(response.map(|_| Body::empty()))
});
Source

fn or_else<F, Fut, Err>(self, f: F) -> OrElse<Self, F>
where Self: Sized, F: Fn(Self::Error) -> Fut + Send + Sync, Fut: Future<Output = Result<Self::Response, Err>> + Send,

在此服务执行失败后执行给定的异步函数。

§例子
use boluo_core::handler::handler_fn;
use boluo_core::http::StatusCode;
use boluo_core::response::IntoResponse;
use boluo_core::service::ServiceExt;

#[derive(Debug)]
struct MyError;

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "some error message")
    }
}

impl std::error::Error for MyError {}

async fn throw_error() -> Result<(), MyError> {
    Err(MyError)
}

let service = handler_fn(throw_error);
let service = service.or_else(|err| async move {
    // 捕获错误并转换为响应。
    if let Some(e) = err.downcast_ref::<MyError>() {
        let status = StatusCode::INTERNAL_SERVER_ERROR;
        return Ok((status, format!("{e}")).into_response()?);
    }
    Err(err)
});
Source

fn map_result<F, Res, Err>(self, f: F) -> MapResult<Self, F>
where Self: Sized, F: Fn(Result<Self::Response, Self::Error>) -> Result<Res, Err> + Send + Sync,

将此服务返回的结果映射为其他值。

§例子
use std::convert::Infallible;

use boluo_core::response::{IntoResponse, Response};
use boluo_core::service::{service_fn, ServiceExt};

#[derive(Debug)]
struct MyError;

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "some error message")
    }
}

impl std::error::Error for MyError {}

async fn throw_error(_: ()) -> Result<(), MyError> {
    Err(MyError)
}

let service = service_fn(throw_error);
let service = service.map_result(|result| -> Result<Response, Infallible> {
    match result {
        Ok(r) => r.into_response(),
        Err(e) => format!("{e}").into_response(),
    }
});
Source

fn map_response<F, Res>(self, f: F) -> MapResponse<Self, F>
where Self: Sized, F: Fn(Self::Response) -> Res + Send + Sync,

将此服务返回的响应映射为其他值。

§例子
use std::convert::Infallible;

use boluo_core::body::Body;
use boluo_core::service::{service_fn, ServiceExt};

async fn hello(_: ()) -> Result<&'static str, Infallible> {
    Ok("Hello, World!")
}

let service = service_fn(hello);
let service = service.map_response(|text| Body::from(text));
Source

fn map_err<F, Err>(self, f: F) -> MapErr<Self, F>
where Self: Sized, F: Fn(Self::Error) -> Err + Send + Sync,

将此服务返回的错误映射为其他值。

§例子
use boluo_core::service::{service_fn, ServiceExt};
use boluo_core::BoxError;

#[derive(Debug)]
struct MyError;

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "some error message")
    }
}

impl std::error::Error for MyError {}

async fn throw_error(_: ()) -> Result<(), MyError> {
    Err(MyError)
}

let service = service_fn(throw_error);
let service = service.map_err(|err| BoxError::from(err));
Source

fn map_request<F, R>(self, f: F) -> MapRequest<Self, F>
where Self: Sized, F: Fn(R) -> Req + Send + Sync,

将发送给此服务的请求映射为其他值。

§例子
use std::convert::Infallible;

use boluo_core::service::{service_fn, Service, ServiceExt};

async fn echo(text: String) -> Result<String, Infallible> {
    Ok(text)
}

let service = service_fn(echo);
let service = service.map_request(|slice: &[u8]| {
    // 将字节片转换为包含无效字符的字符串。
    String::from_utf8_lossy(slice).into_owned()
});

let fut = service.call(b"Hello, World");
Source

fn boxed(self) -> BoxService<Req, Self::Response, Self::Error>
where Self: Sized + 'static,

将此服务转换为 Service 特征对象并装箱。

更多详细信息,请参阅 BoxService

Source

fn boxed_clone(self) -> BoxCloneService<Req, Self::Response, Self::Error>
where Self: Sized + Clone + 'static,

将此服务转换为 Service 特征对象并装箱。

更多详细信息,请参阅 BoxCloneService

Source

fn boxed_arc(self) -> ArcService<Req, Self::Response, Self::Error>
where Self: Sized + 'static,

将此服务转换为 Service 特征对象并装箱。

更多详细信息,请参阅 ArcService

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<S, Req> ServiceExt<Req> for S
where S: Service<Req> + ?Sized,