1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-23 19:51:06 +01:00

update ignored service docs to new traits

This commit is contained in:
Rob Ede 2021-04-15 20:13:27 +01:00
parent 8e98d9168c
commit ef206f40fb
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
2 changed files with 72 additions and 21 deletions

View File

@ -53,8 +53,14 @@ use self::ready::{err, ok, ready, Ready};
/// async fn(Request) -> Result<Response, Err>
/// ```
///
/// The `Service` trait just generalizes this form where each parameter is described as an
/// associated type on the trait. Services can also have mutable state that influence computation.
/// The `Service` trait just generalizes this form. Requests are defined as a generic type parameter
/// and responses and other details are defined as associated types on the trait impl. Notice that
/// this design means that services can receive many request types and converge them to a single
/// response type.
///
/// Services can also have mutable state that influence computation by using a `Cell`, `RefCell`
/// or `Mutex`. Services intentionally do not take `&mut self` to reduce over-head in the
/// common cases.
///
/// `Service` provides a symmetric and uniform API; the same abstractions can be used to represent
/// both clients and servers. Services describe only _transformation_ operations which encourage
@ -64,8 +70,7 @@ use self::ready::{err, ok, ready, Ready};
/// ```ignore
/// struct MyService;
///
/// impl Service for MyService {
/// type Request = u8;
/// impl Service<u8> for MyService {
/// type Response = u64;
/// type Error = MyError;
/// type Future = Pin<Box<Future<Output=Result<Self::Response, Self::Error>>>>;
@ -81,6 +86,9 @@ use self::ready::{err, ok, ready, Ready};
///
/// ```ignore
/// async fn my_service(req: u8) -> Result<u64, MyError>;
///
/// let svc = fn_service(my_service)
/// svc.call(123)
/// ```
pub trait Service<Req> {
/// Responses given by the service.
@ -144,7 +152,7 @@ pub trait ServiceFactory<Req> {
/// Errors potentially raised while building a service.
type InitError;
/// The future of the `Service` instance.
/// The future of the `Service` instance.g
type Future: Future<Output = Result<Self::Service, Self::InitError>>;
/// Create and return a new service asynchronously.

View File

@ -27,7 +27,7 @@ where
/// Transform(middleware) wraps inner service and runs during inbound and/or outbound processing in
/// the request/response lifecycle. It may modify request and/or response.
///
/// For example, timeout transform:
/// For example, a timeout service wrapper:
///
/// ```ignore
/// pub struct Timeout<S> {
@ -35,11 +35,7 @@ where
/// timeout: Duration,
/// }
///
/// impl<S> Service for Timeout<S>
/// where
/// S: Service,
/// {
/// type Request = S::Request;
/// impl<S: Service<Req>, Req> Service<Req> for Timeout<S> {
/// type Response = S::Response;
/// type Error = TimeoutError<S::Error>;
/// type Future = TimeoutServiceResponse<S>;
@ -55,26 +51,22 @@ where
/// }
/// ```
///
/// Timeout service in above example is decoupled from underlying service implementation and could
/// be applied to any service.
/// This wrapper service is decoupled from the underlying service implementation and could be
/// applied to any service.
///
/// The `Transform` trait defines the interface of a Service factory. `Transform` is often
/// The `Transform` trait defines the interface of a service wrapper. `Transform` is often
/// implemented for middleware, defining how to construct a middleware Service. A Service that is
/// constructed by the factory takes the Service that follows it during execution as a parameter,
/// assuming ownership of the next Service.
///
/// Factory for `Timeout` middleware from the above example could look like this:
/// A transform for the `Timeout` middleware could look like this:
///
/// ```ignore
/// pub struct TimeoutTransform {
/// timeout: Duration,
/// }
///
/// impl<S> Transform<S> for TimeoutTransform
/// where
/// S: Service,
/// {
/// type Request = S::Request;
/// impl<S: Service<Req>, Req> Transform<S, Req> for TimeoutTransform {
/// type Response = S::Response;
/// type Error = TimeoutError<S::Error>;
/// type InitError = S::Error;
@ -82,7 +74,7 @@ where
/// type Future = Ready<Result<Self::Transform, Self::InitError>>;
///
/// fn new_transform(&self, service: S) -> Self::Future {
/// ready(Ok(TimeoutService {
/// ready(Ok(Timeout {
/// service,
/// timeout: self.timeout,
/// }))
@ -227,3 +219,54 @@ where
}
}
}
#[cfg(test)]
mod tests {
use core::{
future::{ready, Ready},
time::Duration,
};
use super::*;
use crate::Service;
// pseudo-doctest for Transform trait
pub struct TimeoutTransform {
timeout: Duration,
}
// pseudo-doctest for Transform trait
impl<S: Service<Req>, Req> Transform<S, Req> for TimeoutTransform {
type Response = S::Response;
type Error = S::Error;
type InitError = S::Error;
type Transform = Timeout<S>;
type Future = Ready<Result<Self::Transform, Self::InitError>>;
fn new_transform(&self, service: S) -> Self::Future {
ready(Ok(Timeout {
service,
_timeout: self.timeout,
}))
}
}
// pseudo-doctest for Transform trait
pub struct Timeout<S> {
service: S,
_timeout: Duration,
}
// pseudo-doctest for Transform trait
impl<S: Service<Req>, Req> Service<Req> for Timeout<S> {
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
crate::forward_ready!(service);
fn call(&self, req: Req) -> Self::Future {
self.service.call(req)
}
}
}