mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-27 20:12:58 +01:00
update doc strings
This commit is contained in:
parent
1d810b4561
commit
7163e2c2a2
@ -7,7 +7,6 @@
|
|||||||
//! [`AsyncRead`]: #
|
//! [`AsyncRead`]: #
|
||||||
//! [`AsyncWrite`]: #
|
//! [`AsyncWrite`]: #
|
||||||
#![deny(rust_2018_idioms, warnings)]
|
#![deny(rust_2018_idioms, warnings)]
|
||||||
#![allow(clippy::type_complexity)]
|
|
||||||
|
|
||||||
mod bcodec;
|
mod bcodec;
|
||||||
mod framed;
|
mod framed;
|
||||||
|
@ -2,14 +2,13 @@
|
|||||||
name = "actix-service"
|
name = "actix-service"
|
||||||
version = "1.0.0-alpha.4"
|
version = "1.0.0-alpha.4"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix Service"
|
description = "Actix service"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
repository = "https://github.com/actix/actix-net.git"
|
repository = "https://github.com/actix/actix-net.git"
|
||||||
documentation = "https://docs.rs/actix-service/"
|
documentation = "https://docs.rs/actix-service/"
|
||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
workspace = ".."
|
workspace = ".."
|
||||||
|
|
||||||
|
@ -18,6 +18,41 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create `ServiceFactory` for function that can produce services
|
/// Create `ServiceFactory` for function that can produce services
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::io;
|
||||||
|
/// use actix_service::{fn_factory, fn_service, Service, ServiceFactory};
|
||||||
|
/// use futures_util::future::ok;
|
||||||
|
///
|
||||||
|
/// /// Service that divides two usize values.
|
||||||
|
/// async fn div((x, y): (usize, usize)) -> Result<usize, io::Error> {
|
||||||
|
/// if y == 0 {
|
||||||
|
/// Err(io::Error::new(io::ErrorKind::Other, "divide by zdro"))
|
||||||
|
/// } else {
|
||||||
|
/// Ok(x / y)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[actix_rt::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// // Create service factory that produces `div` services
|
||||||
|
/// let factory = fn_factory(|| {
|
||||||
|
/// ok::<_, io::Error>(fn_service(div))
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // construct new service
|
||||||
|
/// let mut srv = factory.new_service(()).await?;
|
||||||
|
///
|
||||||
|
/// // now we can use `div` service
|
||||||
|
/// let result = srv.call((10, 20)).await?;
|
||||||
|
///
|
||||||
|
/// println!("10 / 20 = {}", result);
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn fn_factory<F, Cfg, Srv, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Err>
|
pub fn fn_factory<F, Cfg, Srv, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Err>
|
||||||
where
|
where
|
||||||
Srv: Service,
|
Srv: Service,
|
||||||
@ -27,7 +62,36 @@ where
|
|||||||
FnServiceNoConfig::new(f)
|
FnServiceNoConfig::new(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create `ServiceFactory` for function that accepts config and can produce services
|
/// Create `ServiceFactory` for function that accepts config argument and can produce services
|
||||||
|
///
|
||||||
|
/// Any function that has following form `Fn(Config) -> Future<Output = Service>` could
|
||||||
|
/// act as a `ServiceFactory`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::io;
|
||||||
|
/// use actix_service::{fn_factory_with_config, fn_service, Service, ServiceFactory};
|
||||||
|
/// use futures_util::future::ok;
|
||||||
|
///
|
||||||
|
/// #[actix_rt::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// // Create service factory. factory uses config argument for
|
||||||
|
/// // services it generates.
|
||||||
|
/// let factory = fn_factory_with_config(|y: usize| {
|
||||||
|
/// ok::<_, io::Error>(fn_service(move |x: usize| ok::<_, io::Error>(x * y)))
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // construct new service with config argument
|
||||||
|
/// let mut srv = factory.new_service(10).await?;
|
||||||
|
///
|
||||||
|
/// let result = srv.call(10).await?;
|
||||||
|
/// assert_eq!(result, 100);
|
||||||
|
///
|
||||||
|
/// println!("10 * 10 = {}", result);
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn fn_factory_with_config<F, Fut, Cfg, Srv, Err>(
|
pub fn fn_factory_with_config<F, Fut, Cfg, Srv, Err>(
|
||||||
f: F,
|
f: F,
|
||||||
) -> FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
) -> FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
||||||
|
@ -31,6 +31,42 @@ pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory};
|
|||||||
pub use self::transform::{apply, Transform};
|
pub use self::transform::{apply, Transform};
|
||||||
|
|
||||||
/// An asynchronous function from `Request` to a `Response`.
|
/// An asynchronous function from `Request` to a `Response`.
|
||||||
|
///
|
||||||
|
/// `Service` represents a service that represanting interation, taking requests and giving back
|
||||||
|
/// replies. You can think about service as a function with one argument and result as a return
|
||||||
|
/// type. In general form it looks like `async fn(Req) -> Result<Res, Err>`. `Service`
|
||||||
|
/// trait just generalizing form of this function. Each parameter described as an assotiated type.
|
||||||
|
///
|
||||||
|
/// Services provides a symmetric and uniform API, same abstractions represents
|
||||||
|
/// clients and servers. Services describe only `transforamtion` operation
|
||||||
|
/// which encorouge to simplify api surface and phrases `value transformation`.
|
||||||
|
/// That leads to simplier design of each service. That also allows better testability
|
||||||
|
/// and better composition.
|
||||||
|
///
|
||||||
|
/// Services could be represented in several different forms. In general,
|
||||||
|
/// Service is a type that implements `Service` trait.
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// struct MyService;
|
||||||
|
///
|
||||||
|
/// impl Service for MyService {
|
||||||
|
/// type Request = u8;
|
||||||
|
/// type Response = u64;
|
||||||
|
/// type Error = MyError;
|
||||||
|
/// type Future = Pin<Box<Future<Output=Result<Self::Response, Self::Error>>>;
|
||||||
|
///
|
||||||
|
/// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... }
|
||||||
|
///
|
||||||
|
/// fn call(&mut self) -> Self::Future { ... }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Service can have mutable state that influence computation.
|
||||||
|
/// This service could be rewritten as a simple function:
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// async fn my_service(req: u8) -> Result<u64, MyError>;
|
||||||
|
/// ```
|
||||||
pub trait Service {
|
pub trait Service {
|
||||||
/// Requests handled by the service.
|
/// Requests handled by the service.
|
||||||
type Request;
|
type Request;
|
||||||
@ -53,6 +89,12 @@ pub trait Service {
|
|||||||
/// This is a **best effort** implementation. False positives are permitted.
|
/// This is a **best effort** implementation. False positives are permitted.
|
||||||
/// It is permitted for the service to return `Ready` from a `poll_ready`
|
/// It is permitted for the service to return `Ready` from a `poll_ready`
|
||||||
/// call and the next invocation of `call` results in an error.
|
/// call and the next invocation of `call` results in an error.
|
||||||
|
///
|
||||||
|
/// There are several notes to consider:
|
||||||
|
///
|
||||||
|
/// 1. `.poll_ready()` might be called on different task from actual service call.
|
||||||
|
///
|
||||||
|
/// 2. In case of chained services, `.poll_ready()` get called for all services at once.
|
||||||
fn poll_ready(&mut self, ctx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
fn poll_ready(&mut self, ctx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
||||||
|
|
||||||
/// Process the request and return the response asynchronously.
|
/// Process the request and return the response asynchronously.
|
||||||
@ -287,7 +329,7 @@ pub trait IntoServiceFactory<T>
|
|||||||
where
|
where
|
||||||
T: ServiceFactory,
|
T: ServiceFactory,
|
||||||
{
|
{
|
||||||
/// Convert `Self` an `ServiceFactory`
|
/// Convert `Self` to a `ServiceFactory`
|
||||||
fn into_factory(self) -> T;
|
fn into_factory(self) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use super::ServiceFactory;
|
use super::ServiceFactory;
|
||||||
|
|
||||||
/// Adapt external config to a config for provided new service
|
/// Adapt external config argument to a config for provided service factory
|
||||||
|
///
|
||||||
|
/// Note that this function consumes the receiving service factory and returns
|
||||||
|
/// a wrapped version of it.
|
||||||
pub fn map_config<T, F, C>(factory: T, f: F) -> MapConfig<T, F, C>
|
pub fn map_config<T, F, C>(factory: T, f: F) -> MapConfig<T, F, C>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
T: ServiceFactory,
|
||||||
|
@ -9,6 +9,7 @@ use crate::map_init_err::MapInitErr;
|
|||||||
use crate::then::{ThenService, ThenServiceFactory};
|
use crate::then::{ThenService, ThenServiceFactory};
|
||||||
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
|
/// Contruct new pipeline with one service in pipeline chain.
|
||||||
pub fn pipeline<F, T>(service: F) -> Pipeline<T>
|
pub fn pipeline<F, T>(service: F) -> Pipeline<T>
|
||||||
where
|
where
|
||||||
F: IntoService<T>,
|
F: IntoService<T>,
|
||||||
@ -19,6 +20,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contruct new pipeline factory with one service factory.
|
||||||
pub fn pipeline_factory<T, F>(factory: F) -> PipelineFactory<T>
|
pub fn pipeline_factory<T, F>(factory: F) -> PipelineFactory<T>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
T: ServiceFactory,
|
||||||
|
@ -19,11 +19,78 @@ where
|
|||||||
ApplyTransform::new(t, service.into_factory())
|
ApplyTransform::new(t, service.into_factory())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `Transform` trait defines the interface of a service factory that wraps inner service
|
||||||
|
/// during construction.
|
||||||
|
///
|
||||||
|
/// 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:
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// pub struct Timeout<S> {
|
||||||
|
/// service: S,
|
||||||
|
/// timeout: Duration,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl<S> Service for Timeout<S>
|
||||||
|
/// where
|
||||||
|
/// S: Service,
|
||||||
|
/// {
|
||||||
|
/// type Request = S::Request;
|
||||||
|
/// type Response = S::Response;
|
||||||
|
/// type Error = TimeoutError<S::Error>;
|
||||||
|
/// type Future = TimeoutServiceResponse<S>;
|
||||||
|
///
|
||||||
|
/// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
/// ready!(self.service.poll_ready(cx)).map_err(TimeoutError::Service)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn call(&mut self, req: S::Request) -> Self::Future {
|
||||||
|
/// TimeoutServiceResponse {
|
||||||
|
/// fut: self.service.call(req),
|
||||||
|
/// sleep: Delay::new(clock::now() + self.timeout),
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Timeout service in above example is decoupled from underlying service implementation
|
||||||
|
/// and could be applied to any service.
|
||||||
|
///
|
||||||
/// The `Transform` trait defines the interface of a Service factory. `Transform`
|
/// The `Transform` trait defines the interface of a Service factory. `Transform`
|
||||||
/// is often implemented for middleware, defining how to construct a
|
/// is often implemented for middleware, defining how to construct a
|
||||||
/// middleware Service. A Service that is constructed by the factory takes
|
/// middleware Service. A Service that is constructed by the factory takes
|
||||||
/// the Service that follows it during execution as a parameter, assuming
|
/// the Service that follows it during execution as a parameter, assuming
|
||||||
/// ownership of the next Service.
|
/// ownership of the next Service.
|
||||||
|
///
|
||||||
|
/// Factory for `Timeout` middleware from the above example could look like this:
|
||||||
|
///
|
||||||
|
/// ```rust,,ignore
|
||||||
|
/// pub struct TimeoutTransform {
|
||||||
|
/// timeout: Duration,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl<S> Transform<S> for TimeoutTransform<E>
|
||||||
|
/// where
|
||||||
|
/// S: Service,
|
||||||
|
/// {
|
||||||
|
/// type Request = S::Request;
|
||||||
|
/// type Response = S::Response;
|
||||||
|
/// type Error = TimeoutError<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 {
|
||||||
|
/// ok(TimeoutService {
|
||||||
|
/// service,
|
||||||
|
/// timeout: self.timeout,
|
||||||
|
/// })
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub trait Transform<S> {
|
pub trait Transform<S> {
|
||||||
/// Requests handled by the service.
|
/// Requests handled by the service.
|
||||||
type Request;
|
type Request;
|
||||||
@ -41,13 +108,13 @@ pub trait Transform<S> {
|
|||||||
Error = Self::Error,
|
Error = Self::Error,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// Errors produced while building a service.
|
/// Errors produced while building a transform service.
|
||||||
type InitError;
|
type InitError;
|
||||||
|
|
||||||
/// The future response value.
|
/// The future response value.
|
||||||
type Future: Future<Output = Result<Self::Transform, Self::InitError>>;
|
type Future: Future<Output = Result<Self::Transform, Self::InitError>>;
|
||||||
|
|
||||||
/// Creates and returns a new Service component, asynchronously
|
/// Creates and returns a new Transform component, asynchronously
|
||||||
fn new_transform(&self, service: S) -> Self::Future;
|
fn new_transform(&self, service: S) -> Self::Future;
|
||||||
|
|
||||||
/// Map this transforms's factory error to a different error,
|
/// Map this transforms's factory error to a different error,
|
||||||
|
@ -3,7 +3,7 @@ use std::marker::PhantomData;
|
|||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
pub use open_ssl::ssl::{SslAcceptor, SslAcceptorBuilder, AlpnError};
|
pub use open_ssl::ssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
|
||||||
pub use tokio_openssl::{HandshakeError, SslStream};
|
pub use tokio_openssl::{HandshakeError, SslStream};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
|
Loading…
Reference in New Issue
Block a user