Skip to content

Commit

Permalink
Unify route macros (actix#1705)
Browse files Browse the repository at this point in the history
  • Loading branch information
arniu authored Sep 22, 2020
1 parent f7bcad9 commit 162121b
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 214 deletions.
216 changes: 79 additions & 137 deletions actix-web-codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,161 +1,103 @@
#![recursion_limit = "512"]

//! Helper and convenience macros for Actix-web.
//!
//! ## Runtime Setup
//!
//! - [main](attr.main.html)
//!
//! ## Resource Macros:
//!
//! - [get](attr.get.html)
//! - [post](attr.post.html)
//! - [put](attr.put.html)
//! - [delete](attr.delete.html)
//! - [head](attr.head.html)
//! - [connect](attr.connect.html)
//! - [options](attr.options.html)
//! - [trace](attr.trace.html)
//! - [patch](attr.patch.html)
//!
//! ### Attributes:
//!
//! - `"path"` - Raw literal string with path for which to register handle. Mandatory.
//! - `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
//! code (e.g `my_guard` or `my_module::my_guard`)
//!
//! ### Example:
//!
//! ```rust
//! use actix_web::HttpResponse;
//! use actix_web_codegen::get;
//!
//! #[get("/test")]
//! async fn async_test() -> Result<HttpResponse, actix_web::Error> {
//! Ok(HttpResponse::Ok().finish())
//! }
//! ```
extern crate proc_macro;

mod route;

use proc_macro::TokenStream;

/// Creates route handler with `GET` method guard.
///
/// Syntax: `#[get("path" [, attributes])]`
///
/// ## Attributes:
///
/// - `"path"` - Raw literal string with path for which to register handler. Mandatory.
/// - `guard = "function_name"` - Registers function as guard using `actix_web::guard::fn_guard`
/// - `wrap = "Middleware"` - Registers a resource middleware.
#[proc_macro_attribute]
pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Get)
}

/// Creates route handler with `POST` method guard.
///
/// Syntax: `#[post("path" [, attributes])]`
///
/// Attributes are the same as in [get](attr.get.html)
#[proc_macro_attribute]
pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Post)
}

/// Creates route handler with `PUT` method guard.
///
/// Syntax: `#[put("path" [, attributes])]`
///
/// Attributes are the same as in [get](attr.get.html)
#[proc_macro_attribute]
pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Put)
}
mod route;

/// Creates route handler with `DELETE` method guard.
/// Creates resource handler, allowing multiple HTTP method guards.
///
/// Syntax: `#[delete("path" [, attributes])]`
/// ## Syntax
/// ```text
/// #[route("path", method="HTTP_METHOD"[, attributes])]
/// ```
///
/// Attributes are the same as in [get](attr.get.html).
#[proc_macro_attribute]
pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Delete)
}

/// Creates route handler with `HEAD` method guard.
/// ### Attributes
/// - `"path"` - Raw literal string with path for which to register handler.
/// - `method="HTTP_METHOD"` - Registers HTTP method to provide guard for. Upper-case string, "GET", "POST" for example.
/// - `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`
/// - `wrap="Middleware"` - Registers a resource middleware.
///
/// Syntax: `#[head("path" [, attributes])]`
/// ### Notes
/// 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`.
///
/// Attributes are the same as in [get](attr.get.html).
#[proc_macro_attribute]
pub fn head(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Head)
}

/// Creates route handler with `CONNECT` method guard.
/// ## Example
///
/// Syntax: `#[connect("path" [, attributes])]`
/// ```rust
/// use actix_web::HttpResponse;
/// use actix_web_codegen::route;
///
/// Attributes are the same as in [get](attr.get.html).
/// #[route("/", method="GET", method="HEAD")]
/// async fn example() -> HttpResponse {
/// HttpResponse::Ok().finish()
/// }
/// ```
#[proc_macro_attribute]
pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Connect)
pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
route::with_method(None, args, input)
}

/// Creates route handler with `OPTIONS` method guard.
///
/// Syntax: `#[options("path" [, attributes])]`
///
/// Attributes are the same as in [get](attr.get.html).
#[proc_macro_attribute]
pub fn options(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Options)
macro_rules! doc_comment {
($x:expr; $($tt:tt)*) => {
#[doc = $x]
$($tt)*
};
}

/// Creates route handler with `TRACE` method guard.
///
/// Syntax: `#[trace("path" [, attributes])]`
///
/// Attributes are the same as in [get](attr.get.html).
#[proc_macro_attribute]
pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Trace)
macro_rules! method_macro {
(
$($variant:ident, $method:ident,)+
) => {
$(doc_comment! {
concat!("
Creates route handler with `actix_web::guard::", stringify!($variant), "`.
## Syntax
```text
#[", stringify!($method), r#"("path"[, attributes])]
```
### Attributes
- `"path"` - Raw literal string with path for which to register handler.
- `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
code, e.g `my_guard` or `my_module::my_guard`.
## Example
```rust
use actix_web::HttpResponse;
use actix_web_codegen::"#, stringify!($method), ";
#[", stringify!($method), r#"("/")]
async fn example() -> HttpResponse {
HttpResponse::Ok().finish()
}

/// Creates route handler with `PATCH` method guard.
///
/// Syntax: `#[patch("path" [, attributes])]`
///
/// Attributes are the same as in [get](attr.get.html).
#[proc_macro_attribute]
pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Patch)
```
"#);
#[proc_macro_attribute]
pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
route::with_method(Some(route::MethodType::$variant), args, input)
}
})+
};
}

/// Creates resource handler, allowing multiple HTTP method guards.
///
/// Syntax: `#[route("path"[, attributes])]`
///
/// Example: `#[route("/", method="GET", method="HEAD")]`
///
/// ## Attributes
///
/// - `"path"` - Raw literal string with path for which to register handler. Mandatory.
/// - `method="HTTP_METHOD"` - Registers HTTP method to provide guard for.
/// - `guard="function_name"` - Registers function as guard using `actix_web::guard::fn_guard`
/// - `wrap="Middleware"` - Registers a resource middleware.
#[proc_macro_attribute]
pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
route::generate(args, input, route::GuardType::Multi)
method_macro! {
Get, get,
Post, post,
Put, put,
Delete, delete,
Head, head,
Connect, connect,
Options, options,
Trace, trace,
Patch, patch,
}

/// Marks async main function as the actix system entry-point.
Expand Down
Loading

0 comments on commit 162121b

Please sign in to comment.