mirror of https://github.com/fafhrd91/actix-web
doc tweaks
This commit is contained in:
parent
4c8cd8a8e7
commit
9eb77c0f89
|
@ -1,11 +1,11 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
- Remove the unused `ResourceInfo`. [#2612]
|
- Remove unused `ResourceInfo`. [#2612]
|
||||||
- Add `RouterBuilder::push`. [#2612]
|
- Add `RouterBuilder::push`. [#2612]
|
||||||
- Change signature of `ResourceDef::capture_match_info_fn` to remove `user_data` parameter. [#2612]
|
- Change signature of `ResourceDef::capture_match_info_fn` to remove `user_data` parameter. [#2612]
|
||||||
- Replace `Option<U>` with `U` in `Router` api. [#2612]
|
- Replace `Option<U>` with `U` in `Router` API. [#2612]
|
||||||
- Relax bounds in `Router::recognize*` and `ResourceDef::capture_match_info`. [#2612]
|
- Relax bounds on `Router::recognize*` and `ResourceDef::capture_match_info`. [#2612]
|
||||||
- `Quoter::requote` now returns `Option<Vec<u8>>`. [#2613]
|
- `Quoter::requote` now returns `Option<Vec<u8>>`. [#2613]
|
||||||
|
|
||||||
[#2612]: https://github.com/actix/actix-web/pull/2612
|
[#2612]: https://github.com/actix/actix-web/pull/2612
|
||||||
|
|
|
@ -64,14 +64,14 @@ impl Quoter {
|
||||||
quoter
|
quoter
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Re-quotes... ?
|
/// Decodes safe percent-encoded sequences from `val`.
|
||||||
///
|
///
|
||||||
/// Returns `None` when no modification to the original byte string was required.
|
/// Returns `None` when no modification to the original byte string was required.
|
||||||
///
|
///
|
||||||
/// Non-ASCII bytes are accepted as valid input.
|
/// Non-ASCII bytes are accepted as valid input.
|
||||||
///
|
///
|
||||||
/// Behavior for invalid/incomplete percent-encoding sequences is unspecified and may include removing
|
/// Behavior for invalid/incomplete percent-encoding sequences is unspecified and may include
|
||||||
/// the invalid sequence from the output or passing it as it is.
|
/// removing the invalid sequence from the output or passing it as-is.
|
||||||
pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>> {
|
pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>> {
|
||||||
let mut has_pct = 0;
|
let mut has_pct = 0;
|
||||||
let mut pct = [b'%', 0, 0];
|
let mut pct = [b'%', 0, 0];
|
||||||
|
|
|
@ -632,9 +632,9 @@ impl ResourceDef {
|
||||||
/// assert_eq!(path.get("path").unwrap(), "HEAD/Cargo.toml");
|
/// assert_eq!(path.get("path").unwrap(), "HEAD/Cargo.toml");
|
||||||
/// assert_eq!(path.unprocessed(), "");
|
/// assert_eq!(path.unprocessed(), "");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn capture_match_info<R: Resource>(&self, path: &mut R) -> bool {
|
pub fn capture_match_info<R: Resource>(&self, resource: &mut R) -> bool {
|
||||||
profile_method!(capture_match_info);
|
profile_method!(capture_match_info);
|
||||||
self.capture_match_info_fn(path, |_| true)
|
self.capture_match_info_fn(resource, |_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collects dynamic segment values into `resource` after matching paths and executing
|
/// Collects dynamic segment values into `resource` after matching paths and executing
|
||||||
|
@ -651,11 +651,11 @@ impl ResourceDef {
|
||||||
/// ```
|
/// ```
|
||||||
/// use actix_router::{Path, ResourceDef};
|
/// use actix_router::{Path, ResourceDef};
|
||||||
///
|
///
|
||||||
/// fn try_match(resource: &ResourceDef, path: &mut Path<&str>) -> bool {
|
/// fn try_match(resource: &ResourceDef, resource: &mut Path<&str>) -> bool {
|
||||||
/// let admin_allowed = std::env::var("ADMIN_ALLOWED").is_ok();
|
/// let admin_allowed = std::env::var("ADMIN_ALLOWED").is_ok();
|
||||||
///
|
///
|
||||||
/// resource.capture_match_info_fn(
|
/// resource.capture_match_info_fn(
|
||||||
/// path,
|
/// resource,
|
||||||
/// // when env var is not set, reject when path contains "admin"
|
/// // when env var is not set, reject when path contains "admin"
|
||||||
/// |res| !(!admin_allowed && res.path().contains("admin")),
|
/// |res| !(!admin_allowed && res.path().contains("admin")),
|
||||||
/// )
|
/// )
|
||||||
|
|
|
@ -7,22 +7,25 @@ pub struct ResourceId(pub u16);
|
||||||
|
|
||||||
/// Resource router.
|
/// Resource router.
|
||||||
///
|
///
|
||||||
/// It matches a [routable resource](Resource) to an ordered list of _routes_,
|
/// It matches a [routing resource](Resource) to an ordered list of _routes_. Each is defined by a
|
||||||
/// each is defined by an single [`ResourceDef`] and containes two types of custom data:
|
/// single [`ResourceDef`] and contains two types of custom data:
|
||||||
/// 1. The route _value_, of the generic type `T`.
|
/// 1. The route _value_, of the generic type `T`.
|
||||||
/// 2. Some _context_ data, of the generic type `U`, which is only provided to the check function in
|
/// 1. Some _context_ data, of the generic type `U`, which is only provided to the check function in
|
||||||
/// [`recognize_fn`](Self::recognize_fn).
|
/// [`recognize_fn`](Self::recognize_fn). This parameter defaults to `()` and can be omitted if
|
||||||
|
/// not required.
|
||||||
pub struct Router<T, U = ()> {
|
pub struct Router<T, U = ()> {
|
||||||
routes: Vec<(ResourceDef, (T, U))>,
|
routes: Vec<(ResourceDef, T, U)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> Router<T, U> {
|
impl<T, U> Router<T, U> {
|
||||||
|
/// Constructs new `RouterBuilder` with empty route list.
|
||||||
pub fn build() -> RouterBuilder<T, U> {
|
pub fn build() -> RouterBuilder<T, U> {
|
||||||
RouterBuilder { routes: Vec::new() }
|
RouterBuilder { routes: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the value in the router that matches a given [routable resource](Resource)
|
/// Finds the value in the router that matches a given [routing resource](Resource).
|
||||||
/// and stores the match result, including the captured dynamic segments, into the `resource`.
|
///
|
||||||
|
/// The match result, including the captured dynamic segments, in the `resource`.
|
||||||
pub fn recognize<R>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
|
pub fn recognize<R>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
|
||||||
where
|
where
|
||||||
R: Resource,
|
R: Resource,
|
||||||
|
@ -31,8 +34,7 @@ impl<T, U> Router<T, U> {
|
||||||
self.recognize_fn(resource, |_, _| true)
|
self.recognize_fn(resource, |_, _| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`recognize`](Self::recognize),
|
/// Same as [`recognize`](Self::recognize) but returns a mutable reference to the matched value.
|
||||||
/// but returns a mutable reference to the matching value.
|
|
||||||
pub fn recognize_mut<R>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)>
|
pub fn recognize_mut<R>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)>
|
||||||
where
|
where
|
||||||
R: Resource,
|
R: Resource,
|
||||||
|
@ -41,12 +43,13 @@ impl<T, U> Router<T, U> {
|
||||||
self.recognize_mut_fn(resource, |_, _| true)
|
self.recognize_mut_fn(resource, |_, _| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`recognize`](Self::recognize),
|
/// Finds the value in the router that matches a given [routing resource](Resource) and passes
|
||||||
/// but executes an additional check function before accepting the route
|
/// an additional predicate check using context data.
|
||||||
/// as fully matched and storing the match result into `resource`.
|
|
||||||
///
|
///
|
||||||
/// The check function is provided with a reference to the `resource` itself
|
/// Similar to [`recognize`](Self::recognize). However, before accepting the route as matched,
|
||||||
/// and to the context data of the route being matched.
|
/// the `check` closure is executed, passing the resource and each route's context data. If the
|
||||||
|
/// closure returns true then the match result is stored into `resource` and a reference to
|
||||||
|
/// the matched _value_ is returned.
|
||||||
pub fn recognize_fn<R, F>(&self, resource: &mut R, mut check: F) -> Option<(&T, ResourceId)>
|
pub fn recognize_fn<R, F>(&self, resource: &mut R, mut check: F) -> Option<(&T, ResourceId)>
|
||||||
where
|
where
|
||||||
R: Resource,
|
R: Resource,
|
||||||
|
@ -54,7 +57,7 @@ impl<T, U> Router<T, U> {
|
||||||
{
|
{
|
||||||
profile_method!(recognize_checked);
|
profile_method!(recognize_checked);
|
||||||
|
|
||||||
for (rdef, (val, ctx)) in self.routes.iter() {
|
for (rdef, val, ctx) in self.routes.iter() {
|
||||||
if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
|
if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
|
||||||
return Some((val, ResourceId(rdef.id())));
|
return Some((val, ResourceId(rdef.id())));
|
||||||
}
|
}
|
||||||
|
@ -63,8 +66,8 @@ impl<T, U> Router<T, U> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`recognize_fn`](Self::recognize),
|
/// Same as [`recognize_fn`](Self::recognize_fn) but returns a mutable reference to the matched
|
||||||
/// but returns a mutable reference to the matching value.
|
/// value.
|
||||||
pub fn recognize_mut_fn<R, F>(
|
pub fn recognize_mut_fn<R, F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
resource: &mut R,
|
resource: &mut R,
|
||||||
|
@ -76,7 +79,7 @@ impl<T, U> Router<T, U> {
|
||||||
{
|
{
|
||||||
profile_method!(recognize_mut_checked);
|
profile_method!(recognize_mut_checked);
|
||||||
|
|
||||||
for (rdef, (val, ctx)) in self.routes.iter_mut() {
|
for (rdef, val, ctx) in self.routes.iter_mut() {
|
||||||
if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
|
if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
|
||||||
return Some((val, ResourceId(rdef.id())));
|
return Some((val, ResourceId(rdef.id())));
|
||||||
}
|
}
|
||||||
|
@ -86,25 +89,26 @@ impl<T, U> Router<T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the list of routes for a [resource router](Router).
|
/// Builder for an ordered [routing](Router) list.
|
||||||
pub struct RouterBuilder<T, U = ()> {
|
pub struct RouterBuilder<T, U = ()> {
|
||||||
routes: Vec<(ResourceDef, (T, U))>,
|
routes: Vec<(ResourceDef, T, U)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> RouterBuilder<T, U> {
|
impl<T, U> RouterBuilder<T, U> {
|
||||||
/// Adds a new route at the back of the routes list.
|
/// Adds a new route to the end of the routing list.
|
||||||
///
|
///
|
||||||
/// Returns a mutable reference to elements of the new route.
|
/// Returns mutable references to elements of the new route.
|
||||||
pub fn push(
|
pub fn push(
|
||||||
&mut self,
|
&mut self,
|
||||||
rdef: ResourceDef,
|
rdef: ResourceDef,
|
||||||
val: T,
|
val: T,
|
||||||
ctx: U,
|
ctx: U,
|
||||||
) -> (&mut ResourceDef, &mut T, &mut U) {
|
) -> (&mut ResourceDef, &mut T, &mut U) {
|
||||||
self.routes.push((rdef, (val, ctx)));
|
profile_method!(push);
|
||||||
|
self.routes.push((rdef, val, ctx));
|
||||||
self.routes
|
self.routes
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.map(|(rdef, (val, ctx))| (rdef, val, ctx))
|
.map(|(rdef, val, ctx)| (rdef, val, ctx))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +145,7 @@ where
|
||||||
self.push(ResourceDef::prefix(prefix), val, U::default())
|
self.push(ResourceDef::prefix(prefix), val, U::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers resource for ResourceDef.
|
/// Registers resource for [`ResourceDef`].
|
||||||
pub fn rdef(&mut self, rdef: ResourceDef, val: T) -> (&mut ResourceDef, &mut T, &mut U) {
|
pub fn rdef(&mut self, rdef: ResourceDef, val: T) -> (&mut ResourceDef, &mut T, &mut U) {
|
||||||
profile_method!(rdef);
|
profile_method!(rdef);
|
||||||
self.push(rdef, val, U::default())
|
self.push(rdef, val, U::default())
|
||||||
|
|
|
@ -21,8 +21,6 @@ use crate::{
|
||||||
Error, HttpResponse,
|
Error, HttpResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
|
||||||
|
|
||||||
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
|
||||||
///
|
///
|
||||||
/// It also executes data factories.
|
/// It also executes data factories.
|
||||||
|
@ -244,7 +242,7 @@ pub struct AppRoutingFactory {
|
||||||
[(
|
[(
|
||||||
ResourceDef,
|
ResourceDef,
|
||||||
BoxedHttpServiceFactory,
|
BoxedHttpServiceFactory,
|
||||||
RefCell<Option<Guards>>,
|
RefCell<Option<Vec<Box<dyn Guard>>>>,
|
||||||
)],
|
)],
|
||||||
>,
|
>,
|
||||||
default: Rc<BoxedHttpServiceFactory>,
|
default: Rc<BoxedHttpServiceFactory>,
|
||||||
|
@ -262,7 +260,7 @@ impl ServiceFactory<ServiceRequest> for AppRoutingFactory {
|
||||||
// construct all services factory future with it's resource def and guards.
|
// construct all services factory future with it's resource def and guards.
|
||||||
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
let guards = guards.borrow_mut().take();
|
let guards = guards.borrow_mut().take().unwrap_or_default();
|
||||||
let factory_fut = factory.new_service(());
|
let factory_fut = factory.new_service(());
|
||||||
async move {
|
async move {
|
||||||
let service = factory_fut.await?;
|
let service = factory_fut.await?;
|
||||||
|
@ -295,7 +293,7 @@ impl ServiceFactory<ServiceRequest> for AppRoutingFactory {
|
||||||
|
|
||||||
/// The Actix Web router default entry point.
|
/// The Actix Web router default entry point.
|
||||||
pub struct AppRouting {
|
pub struct AppRouting {
|
||||||
router: Router<BoxedHttpService, Option<Guards>>,
|
router: Router<BoxedHttpService, Vec<Box<dyn Guard>>>,
|
||||||
default: BoxedHttpService,
|
default: BoxedHttpService,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +307,7 @@ impl Service<ServiceRequest> for AppRouting {
|
||||||
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
||||||
let res = self.router.recognize_fn(&mut req, |req, guards| {
|
let res = self.router.recognize_fn(&mut req, |req, guards| {
|
||||||
let guard_ctx = req.guard_ctx();
|
let guard_ctx = req.guard_ctx();
|
||||||
guards.iter().flatten().all(|guard| guard.check(&guard_ctx))
|
guards.iter().all(|guard| guard.check(&guard_ctx))
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((srv, _info)) = res {
|
if let Some((srv, _info)) = res {
|
||||||
|
|
|
@ -467,7 +467,7 @@ impl ServiceFactory<ServiceRequest> for ScopeFactory {
|
||||||
// construct all services factory future with it's resource def and guards.
|
// construct all services factory future with it's resource def and guards.
|
||||||
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
let guards = guards.borrow_mut().take();
|
let guards = guards.borrow_mut().take().unwrap_or_default();
|
||||||
let factory_fut = factory.new_service(());
|
let factory_fut = factory.new_service(());
|
||||||
async move {
|
async move {
|
||||||
let service = factory_fut.await?;
|
let service = factory_fut.await?;
|
||||||
|
@ -496,7 +496,7 @@ impl ServiceFactory<ServiceRequest> for ScopeFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ScopeService {
|
pub struct ScopeService {
|
||||||
router: Router<BoxedHttpService, Option<Vec<Box<dyn Guard>>>>,
|
router: Router<BoxedHttpService, Vec<Box<dyn Guard>>>,
|
||||||
default: BoxedHttpService,
|
default: BoxedHttpService,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ impl Service<ServiceRequest> for ScopeService {
|
||||||
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
||||||
let res = self.router.recognize_fn(&mut req, |req, guards| {
|
let res = self.router.recognize_fn(&mut req, |req, guards| {
|
||||||
let guard_ctx = req.guard_ctx();
|
let guard_ctx = req.guard_ctx();
|
||||||
guards.iter().flatten().all(|guard| guard.check(&guard_ctx))
|
guards.iter().all(|guard| guard.check(&guard_ctx))
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((srv, _info)) = res {
|
if let Some((srv, _info)) = res {
|
||||||
|
|
Loading…
Reference in New Issue