1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-12 18:29:34 +00:00

refactor route codegen to be cleaner

This commit is contained in:
Rob Ede 2022-01-20 01:53:02 +00:00
parent 68ad81f989
commit f227e880d7
No known key found for this signature in database
GPG key ID: 97C636207D3EF933
2 changed files with 59 additions and 68 deletions

View file

@ -45,7 +45,12 @@
//! } //! }
//! ``` //! ```
//! //!
//! [actix-web attributes docs]: https://docs.rs/actix-web/*/actix_web/#attributes //! # Multiple Path Handlers
//! There are no macros to generate multi-path handlers. Let us know in [this issue].
//!
//! [this issue]: https://github.com/actix/actix-web/issues/1709
//!
//! [actix-web attributes docs]: https://docs.rs/actix-web/latest/actix_web/#attributes
//! [GET]: macro@get //! [GET]: macro@get
//! [POST]: macro@post //! [POST]: macro@post
//! [PUT]: macro@put //! [PUT]: macro@put
@ -73,24 +78,23 @@ mod route;
/// ``` /// ```
/// ///
/// # Attributes /// # Attributes
/// - `"path"` - Raw literal string with path for which to register handler. /// - `"path"`: Raw literal string with path for which to register handler.
/// - `name = "resource_name"` - Specifies resource name for the handler. If not set, the function /// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the function
/// name of handler is used. /// name of handler is used.
/// - `method = "HTTP_METHOD"` - Registers HTTP method to provide guard for. Upper-case string, /// - `method = "HTTP_METHOD"`: Registers HTTP method to provide guard for. Upper-case string,
/// "GET", "POST" for example. /// "GET", "POST" for example.
/// - `guard = "function_name"` - Registers function as guard using `actix_web::guard::fn_guard` /// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`.
/// - `wrap = "Middleware"` - Registers a resource middleware. /// - `wrap = "Middleware"`: Registers a resource middleware.
/// ///
/// # Notes /// # Notes
/// Function name can be specified as any expression that is going to be accessible to the generate /// Function name can be specified as any expression that is going to be accessible to the generate
/// code, e.g `my_guard` or `my_module::my_guard`. /// code, e.g `my_guard` or `my_module::my_guard`.
/// ///
/// # Example /// # Examples
///
/// ``` /// ```
/// # use actix_web::HttpResponse; /// # use actix_web::HttpResponse;
/// # use actix_web_codegen::route; /// # use actix_web_codegen::route;
/// #[route("/test", method="GET", method="HEAD")] /// #[route("/test", method = "GET", method = "HEAD")]
/// async fn example() -> HttpResponse { /// async fn example() -> HttpResponse {
/// HttpResponse::Ok().finish() /// HttpResponse::Ok().finish()
/// } /// }
@ -100,69 +104,55 @@ pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
route::with_method(None, args, input) route::with_method(None, args, input)
} }
macro_rules! doc_comment {
($x:expr; $($tt:tt)*) => {
#[doc = $x]
$($tt)*
};
}
macro_rules! method_macro { macro_rules! method_macro {
( ($variant:ident, $method:ident) => {
$($variant:ident, $method:ident,)+ #[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")]
) => { ///
$(doc_comment! { /// # Syntax
concat!(" /// ```plain
Creates route handler with `actix_web::guard::", stringify!($variant), "`. #[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)]
/// ```
# Syntax ///
```plain /// # Attributes
#[", stringify!($method), r#"("path"[, attributes])] /// - `"path"`: Raw literal string with path for which to register handler.
``` /// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the
/// function name of handler is used.
# Attributes /// - `guard = "function_name"`: Registers function as guard.
- `"path"` - Raw literal string with path for which to register handler. /// using `actix_web::guard::fn_guard`.
- `name="resource_name"` - Specifies resource name for the handler. If not set, the function name of handler is used. /// - `wrap = "Middleware"`: Registers a resource middleware.
- `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`. ///
- `wrap="Middleware"` - Registers a resource middleware. /// # Notes
/// Function name can be specified as any expression that is going to be accessible to the generate
# Notes /// code, e.g `my_guard` or `my_module::my_guard`.
Function name can be specified as any expression that is going to be accessible to the generate ///
code, e.g `my_guard` or `my_module::my_guard`. /// # Example
/// ```
# Example /// # use actix_web::HttpResponse;
#[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")]
``` #[doc = concat!("#[", stringify!($method), r#"("/")]"#)]
# use actix_web::HttpResponse; /// async fn example() -> HttpResponse {
# use actix_web_codegen::"#, stringify!($method), "; /// HttpResponse::Ok().finish()
#[", stringify!($method), r#"("/")] /// }
async fn example() -> HttpResponse { /// ```
HttpResponse::Ok().finish() #[proc_macro_attribute]
} pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
``` route::with_method(Some(route::MethodType::$variant), args, input)
"#); }
#[proc_macro_attribute]
pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
route::with_method(Some(route::MethodType::$variant), args, input)
}
})+
}; };
} }
method_macro! { method_macro!(Get, get);
Get, get, method_macro!(Post, post);
Post, post, method_macro!(Put, put);
Put, put, method_macro!(Delete, delete);
Delete, delete, method_macro!(Head, head);
Head, head, method_macro!(Connect, connect);
Connect, connect, method_macro!(Options, options);
Options, options, method_macro!(Trace, trace);
Trace, trace, method_macro!(Patch, patch);
Patch, patch,
}
/// Marks async main function as the actix system entry-point.
/// Marks async main function as the Actix Web system entry-point.
///
/// # Examples /// # Examples
/// ``` /// ```
/// #[actix_web::main] /// #[actix_web::main]

View file

@ -899,8 +899,9 @@ mod tests {
test::call_service(&srv, TestRequest::with_uri("/foo/nested").to_request()).await; test::call_service(&srv, TestRequest::with_uri("/foo/nested").to_request()).await;
assert_eq!(foo_resp.status(), StatusCode::OK); assert_eq!(foo_resp.status(), StatusCode::OK);
let body = read_body(foo_resp).await; let body = read_body(foo_resp).await;
// XXX: body equals http://localhost:8080/bar/nested // `body` equals http://localhost:8080/bar/nested
// because nested from /bar overrides /foo's // because nested from /bar overrides /foo's
// to do this any other way would require something like a custom tree search
assert_eq!(body, "http://localhost:8080/bar/nested"); assert_eq!(body, "http://localhost:8080/bar/nested");
let bar_resp = let bar_resp =