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§
Sourcefn with<T, R>(self, middleware: T) -> T::Service
fn with<T, R>(self, middleware: T) -> T::Service
在此服务上应用中间件。
§例子
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));Sourcefn then<F, Fut, Res, Err>(self, f: F) -> Then<Self, F>
fn then<F, Fut, Res, Err>(self, f: F) -> Then<Self, F>
在此服务执行完成后执行给定的异步函数。
§例子
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
});Sourcefn and_then<F, Fut, Res>(self, f: F) -> AndThen<Self, F>
fn and_then<F, Fut, Res>(self, f: F) -> AndThen<Self, F>
在此服务执行成功后执行给定的异步函数。
§例子
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()))
});Sourcefn or_else<F, Fut, Err>(self, f: F) -> OrElse<Self, F>
fn or_else<F, Fut, Err>(self, f: F) -> OrElse<Self, F>
在此服务执行失败后执行给定的异步函数。
§例子
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)
});Sourcefn map_result<F, Res, Err>(self, f: F) -> MapResult<Self, F>
fn map_result<F, Res, Err>(self, f: F) -> MapResult<Self, F>
将此服务返回的结果映射为其他值。
§例子
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(),
}
});Sourcefn map_response<F, Res>(self, f: F) -> MapResponse<Self, F>
fn map_response<F, Res>(self, f: F) -> MapResponse<Self, F>
将此服务返回的响应映射为其他值。
§例子
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));Sourcefn map_err<F, Err>(self, f: F) -> MapErr<Self, F>
fn map_err<F, Err>(self, f: F) -> MapErr<Self, F>
将此服务返回的错误映射为其他值。
§例子
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));Sourcefn map_request<F, R>(self, f: F) -> MapRequest<Self, F>
fn map_request<F, R>(self, f: F) -> MapRequest<Self, F>
将发送给此服务的请求映射为其他值。
§例子
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");Sourcefn boxed(self) -> BoxService<Req, Self::Response, Self::Error>where
Self: Sized + 'static,
fn boxed(self) -> BoxService<Req, Self::Response, Self::Error>where
Self: Sized + 'static,
将此服务转换为 Service 特征对象并装箱。
更多详细信息,请参阅 BoxService。
Sourcefn boxed_clone(self) -> BoxCloneService<Req, Self::Response, Self::Error>
fn boxed_clone(self) -> BoxCloneService<Req, Self::Response, Self::Error>
将此服务转换为 Service 特征对象并装箱。
更多详细信息,请参阅 BoxCloneService。
Sourcefn boxed_arc(self) -> ArcService<Req, Self::Response, Self::Error>where
Self: Sized + 'static,
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.