Skip to content

Commit

Permalink
chore: changelog, docs, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ModProg committed Apr 30, 2022
1 parent 70c4ed7 commit 8a88765
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 4 deletions.
5 changes: 4 additions & 1 deletion actix-web-codegen/CHANGES.md
@@ -1,6 +1,9 @@
# Changes

## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Added `#[actix_web::routes]` macro to support multiple routes on one handler

[#2718]: https://github.com/actix/actix-web/pull/2718


## 4.0.0 - 2022-02-24
Expand Down
43 changes: 41 additions & 2 deletions actix-web-codegen/src/lib.rs
Expand Up @@ -46,9 +46,20 @@
//! ```
//!
//! # Multiple Path Handlers
//! There are no macros to generate multi-path handlers. Let us know in [this issue].
//! Acts as a wrapper for multiple single method handler macros. It takes no arguments and
//! delegates those to the macros for the individual methods. See [macro@routes] macro docs.
//!
//! [this issue]: https://github.com/actix/actix-web/issues/1709
//! ```
//! # use actix_web::HttpResponse;
//! # use actix_web_codegen::routes;
//! #[routes]
//! #[get("/test")]
//! #[get("/test2")]
//! #[delete("/test")]
//! async fn example() -> HttpResponse {
//! HttpResponse::Ok().finish()
//! }
//! ```
//!
//! [actix-web attributes docs]: https://docs.rs/actix-web/latest/actix_web/#attributes
//! [GET]: macro@get
Expand Down Expand Up @@ -104,6 +115,34 @@ pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
route::with_method(None, args, input)
}

/// Creates resource handler, allowing multiple HTTP methods and paths.
///
/// # Syntax
/// ```plain
/// #[routes]
/// #[<method>("path", ...)]
/// #[<method>("path", ...)]
/// ...
/// ```
///
/// # Attributes
/// The `routes` macro it self has no parameters, but allows specifying the attribute macros for
/// the different methods, e.g. [`GET`](macro@get) or [`POST`](macro@post).
///
/// These helper attributes take the same parameters as the [single method handlers](crate#single-method-handler).
///
/// # Examples
/// ```
/// # use actix_web::HttpResponse;
/// # use actix_web_codegen::routes;
/// #[routes]
/// #[get("/test")]
/// #[get("/test2")]
/// #[delete("/test")]
/// async fn example() -> HttpResponse {
/// HttpResponse::Ok().finish()
/// }
/// ```
#[proc_macro_attribute]
pub fn routes(_: TokenStream, input: TokenStream) -> TokenStream {
route::with_methods(input)
Expand Down
25 changes: 24 additions & 1 deletion actix-web-codegen/tests/test_macro.rs
Expand Up @@ -10,7 +10,9 @@ use actix_web::{
},
web, App, Error, HttpResponse, Responder,
};
use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, route, trace};
use actix_web_codegen::{
connect, delete, get, head, options, patch, post, put, route, routes, trace,
};
use futures_core::future::LocalBoxFuture;

// Make sure that we can name function as 'config'
Expand Down Expand Up @@ -89,6 +91,14 @@ async fn route_test() -> impl Responder {
HttpResponse::Ok()
}

#[routes]
#[get("/routes/test")]
#[get("/routes/test2")]
#[post("/routes/test")]
async fn routes_test() -> impl Responder {
HttpResponse::Ok()
}

#[get("/custom_resource_name", name = "custom")]
async fn custom_resource_name_test<'a>(req: actix_web::HttpRequest) -> impl Responder {
assert!(req.url_for_static("custom").is_ok());
Expand Down Expand Up @@ -186,6 +196,7 @@ async fn test_body() {
.service(patch_test)
.service(test_handler)
.service(route_test)
.service(routes_test)
.service(custom_resource_name_test)
});
let request = srv.request(http::Method::GET, srv.url("/test"));
Expand Down Expand Up @@ -242,6 +253,18 @@ async fn test_body() {
let response = request.send().await.unwrap();
assert!(!response.status().is_success());

let request = srv.request(http::Method::GET, srv.url("/routes/test"));
let response = request.send().await.unwrap();
assert!(response.status().is_success());

let request = srv.request(http::Method::GET, srv.url("/routes/test2"));
let response = request.send().await.unwrap();
assert!(response.status().is_success());

let request = srv.request(http::Method::POST, srv.url("/routes/test"));
let response = request.send().await.unwrap();
assert!(response.status().is_success());

let request = srv.request(http::Method::GET, srv.url("/custom_resource_name"));
let response = request.send().await.unwrap();
assert!(response.status().is_success());
Expand Down
2 changes: 2 additions & 0 deletions actix-web-codegen/tests/trybuild.rs
Expand Up @@ -12,6 +12,8 @@ fn compile_macros() {
t.compile_fail("tests/trybuild/route-unexpected-method-fail.rs");
t.compile_fail("tests/trybuild/route-malformed-path-fail.rs");

t.pass("tests/trybuild/routes-ok.rs");

t.pass("tests/trybuild/docstring-ok.rs");

t.pass("tests/trybuild/test-runtime.rs");
Expand Down
23 changes: 23 additions & 0 deletions actix-web-codegen/tests/trybuild/routes-ok.rs
@@ -0,0 +1,23 @@
use actix_web_codegen::*;

#[routes]
#[get("/")]
#[post("/")]
async fn index() -> String {
"Hello World!".to_owned()
}

#[actix_web::main]
async fn main() {
use actix_web::App;

let srv = actix_test::start(|| App::new().service(index));

let request = srv.get("/");
let response = request.send().await.unwrap();
assert!(response.status().is_success());

let request = srv.post("/");
let response = request.send().await.unwrap();
assert!(response.status().is_success());
}
1 change: 1 addition & 0 deletions actix-web/src/lib.rs
Expand Up @@ -132,6 +132,7 @@ macro_rules! codegen_reexport {
codegen_reexport!(main);
codegen_reexport!(test);
codegen_reexport!(route);
codegen_reexport!(routes);
codegen_reexport!(head);
codegen_reexport!(get);
codegen_reexport!(post);
Expand Down

0 comments on commit 8a88765

Please sign in to comment.