Documentation and minor fixes

- Add with_type to catcher
- Documents CatcherType, RouteType, and the associated methods in
LocalResponse.
This commit is contained in:
Matthew Pomes 2022-05-09 12:02:44 -05:00 committed by Sergio Benitez
parent 9aa14d0e24
commit 78aecfdd41
3 changed files with 51 additions and 14 deletions

View File

@ -11,12 +11,10 @@ use crate::catcher::{Handler, BoxFuture};
use yansi::Paint; use yansi::Paint;
// We could also choose to require a Debug impl? /// A generic trait for catcher types. This should be automatically implemented on the structs
/// A generic trait for route types. This should be automatically implemented on the structs /// generated by the codegen for each catcher, and manually implemented on custom cater types.
/// generated by the codegen for each route.
/// ///
/// It may also be desirable to add an option for other routes to define a RouteType. This /// Use the `Catcher::with_type::<T>()` method to set the catcher type.
/// would likely just be a case of adding an alternate constructor to the Route type.
pub trait CatcherType: Any + Send + Sync + 'static { } pub trait CatcherType: Any + Send + Sync + 'static { }
/// An error catching route. /// An error catching route.
@ -183,6 +181,8 @@ impl Catcher {
/// ///
/// Panics if `code` is not in the HTTP status code error range `[400, /// Panics if `code` is not in the HTTP status code error range `[400,
/// 600)`. /// 600)`.
///
/// If applicable, `with_type` should also be called to set the route type for testing
#[inline(always)] #[inline(always)]
pub fn new<S, H>(code: S, handler: H) -> Catcher pub fn new<S, H>(code: S, handler: H) -> Catcher
where S: Into<Option<u16>>, H: Handler where S: Into<Option<u16>>, H: Handler
@ -274,6 +274,13 @@ impl Catcher {
self self
} }
/// Marks this catcher with the specified type. For a custom catcher type, i.e. something that can
/// be passed to `.register()`, it should be that type to make identification easier.
pub fn with_type<T: CatcherType>(mut self) -> Self {
self.catcher_type = Some(TypeId::of::<T>());
self
}
/// Maps the `base` of this catcher using `mapper`, returning a new /// Maps the `base` of this catcher using `mapper`, returning a new
/// `Catcher` with the returned base. /// `Catcher` with the returned base.
/// ///

View File

@ -180,7 +180,8 @@ macro_rules! pub_response_impl {
self._into_msgpack() $(.$suffix)? self._into_msgpack() $(.$suffix)?
} }
/// Checks if a route was routed by a specific route type /// Checks if a route was routed by a specific route type. This only returns true if the route
/// actually generated a response, and a catcher was not run.
/// ///
/// # Example /// # Example
/// ///
@ -194,6 +195,12 @@ macro_rules! pub_response_impl {
/// assert!(response.routed_by::<index>()) /// assert!(response.routed_by::<index>())
/// # }); /// # });
/// ``` /// ```
///
/// # Other Route types
///
/// [`FileServer`](crate::fs::FileServer) implementes `RouteType`, so a route that should
/// return a static file can be checked against it. Libraries which provide a Route type should
/// implement `RouteType`, see [`RouteType`](crate::route::RouteType) for more information.
pub fn routed_by<T: crate::route::RouteType>(&self) -> bool { pub fn routed_by<T: crate::route::RouteType>(&self) -> bool {
if let Some(route_type) = self._request().route().map(|r| r.route_type).flatten() { if let Some(route_type) = self._request().route().map(|r| r.route_type).flatten() {
route_type == std::any::TypeId::of::<T>() route_type == std::any::TypeId::of::<T>()
@ -208,14 +215,18 @@ macro_rules! pub_response_impl {
/// ///
/// ```rust /// ```rust
/// # use rocket::get; /// # use rocket::get;
/// #[get("/")] /// #[catch(404)]
/// fn index() -> &'static str { "Hello World" } /// fn default_404() -> &'static str { "Hello World" }
#[doc = $doc_prelude] #[doc = $doc_prelude]
/// # Client::_test(|_, _, response| { /// # Client::_test(|_, _, response| {
/// let response: LocalResponse = response; /// let response: LocalResponse = response;
/// assert!(response.routed_by::<index>()) /// assert!(response.caught_by::<default_404>())
/// # }); /// # });
/// ``` /// ```
///
/// # Rocket's default catcher
///
/// The default catcher has a `CatcherType` of [`DefaultCatcher`](crate::catcher::DefaultCatcher)
pub fn caught_by<T: crate::catcher::CatcherType>(&self) -> bool { pub fn caught_by<T: crate::catcher::CatcherType>(&self) -> bool {
if let Some(catcher_type) = self._request().catcher().map(|r| r.catcher_type).flatten() { if let Some(catcher_type) = self._request().catcher().map(|r| r.catcher_type).flatten() {
catcher_type == std::any::TypeId::of::<T>() catcher_type == std::any::TypeId::of::<T>()
@ -224,6 +235,22 @@ macro_rules! pub_response_impl {
} }
} }
/// Checks if a route was caught by a catcher
///
/// # Example
///
/// ```rust
/// # use rocket::get;
#[doc = $doc_prelude]
/// # Client::_test(|_, _, response| {
/// let response: LocalResponse = response;
/// assert!(response.was_caught())
/// # });
/// ```
pub fn was_caught(&self) -> bool {
self._request().catcher().is_some()
}
#[cfg(test)] #[cfg(test)]
#[allow(dead_code)] #[allow(dead_code)]
fn _ensure_impls_exist() { fn _ensure_impls_exist() {

View File

@ -9,12 +9,10 @@ use crate::http::{uri, MediaType, Method};
use crate::route::{BoxFuture, Handler, RouteUri}; use crate::route::{BoxFuture, Handler, RouteUri};
use crate::sentinel::Sentry; use crate::sentinel::Sentry;
// We could also choose to require a Debug impl?
/// A generic trait for route types. This should be automatically implemented on the structs /// A generic trait for route types. This should be automatically implemented on the structs
/// generated by the codegen for each route. /// generated by the codegen for each route, and manually implemented on custom route types.
/// ///
/// It may also be desirable to add an option for other routes to define a RouteType. This /// Use the `Route::with_type::<T>()` method to set the route type.
/// would likely just be a case of adding an alternate constructor to the Route type.
pub trait RouteType: Any + Send + Sync + 'static { } pub trait RouteType: Any + Send + Sync + 'static { }
/// A request handling route. /// A request handling route.
@ -219,6 +217,8 @@ impl Route {
/// assert_eq!(index.method, Method::Get); /// assert_eq!(index.method, Method::Get);
/// assert_eq!(index.uri, "/"); /// assert_eq!(index.uri, "/");
/// ``` /// ```
///
/// If applicable, `with_type` should also be called to set the route type for testing
#[track_caller] #[track_caller]
pub fn new<H: Handler>(method: Method, uri: &str, handler: H) -> Route { pub fn new<H: Handler>(method: Method, uri: &str, handler: H) -> Route {
Route::ranked(None, method, uri, handler) Route::ranked(None, method, uri, handler)
@ -254,6 +254,8 @@ impl Route {
/// assert_eq!(foo.method, Method::Post); /// assert_eq!(foo.method, Method::Post);
/// assert_eq!(foo.uri, "/foo?bar"); /// assert_eq!(foo.uri, "/foo?bar");
/// ``` /// ```
///
/// If applicable, `with_type` should also be called to set the route type for testing
#[track_caller] #[track_caller]
pub fn ranked<H, R>(rank: R, method: Method, uri: &str, handler: H) -> Route pub fn ranked<H, R>(rank: R, method: Method, uri: &str, handler: H) -> Route
where where
@ -315,7 +317,8 @@ impl Route {
self self
} }
/// Marks this route with the specified type /// Marks this route with the specified type. For a custom route type, i.e. something that can
/// be passed to `.mount()`, it should be that type to make identification easier.
pub fn with_type<T: RouteType>(mut self) -> Self { pub fn with_type<T: RouteType>(mut self) -> Self {
self.route_type = Some(TypeId::of::<T>()); self.route_type = Some(TypeId::of::<T>());
self self