1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-24 00:21:08 +01:00

prepare codegen 0.4.0 release (#1702)

This commit is contained in:
Rob Ede 2020-09-24 23:54:01 +01:00 committed by GitHub
parent 162121bf8d
commit c53e9468bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 124 additions and 69 deletions

View File

@ -1,6 +1,9 @@
# Changes # Changes
## Unreleased - 2020-xx-xx ## Unreleased - 2020-xx-xx
## 0.4.0 - 2020-09-20
* Added compile success and failure testing. [#1677] * Added compile success and failure testing. [#1677]
* Add `route` macro for supporting multiple HTTP methods guards. * Add `route` macro for supporting multiple HTTP methods guards.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-web-codegen" name = "actix-web-codegen"
version = "0.3.0" version = "0.4.0"
description = "Actix web proc macros" description = "Actix web proc macros"
readme = "README.md" readme = "README.md"
homepage = "https://actix.rs" homepage = "https://actix.rs"
@ -19,7 +19,7 @@ syn = { version = "1", features = ["full", "parsing"] }
proc-macro2 = "1" proc-macro2 = "1"
[dev-dependencies] [dev-dependencies]
actix-rt = "1.0.0" actix-rt = "1.1.1"
actix-web = "3.0.0" actix-web = "3.0.0"
futures-util = { version = "0.3.5", default-features = false } futures-util = { version = "0.3.5", default-features = false }
trybuild = "1" trybuild = "1"

View File

@ -1,6 +1,64 @@
#![recursion_limit = "512"] //! Macros for reducing boilerplate code in Actix Web applications.
//!
//! ## Actix Web Re-exports
//! Actix Web re-exports a version of this crate in it's entirety so you usually don't have to
//! specify a dependency on this crate explicitly. Sometimes, however, updates are made to this
//! crate before the actix-web dependency is updated. Therefore, code examples here will show
//! explicit imports. Check the latest [actix-web attributes docs] to see which macros
//! are re-exported.
//!
//! # Runtime Setup
//! Used for setting up the actix async runtime. See [main] macro docs.
//!
//! ```rust
//! #[actix_web_codegen::main] // or `#[actix_web::main]` in Actix Web apps
//! async fn main() {
//! async { println!("Hello world"); }.await
//! }
//! ```
//!
//! # Single Method Handler
//! There is a macro to set up a handler for each of the most common HTTP methods that also define
//! additional guards and route-specific middleware.
//!
//! See docs for: [GET], [POST], [PATCH], [PUT], [DELETE], [HEAD], [CONNECT], [OPTIONS], [TRACE]
//!
//! ```rust
//! # use actix_web::HttpResponse;
//! # use actix_web_codegen::get;
//! #[get("/test")]
//! async fn get_handler() -> HttpResponse {
//! HttpResponse::Ok().finish()
//! }
//! ```
//!
//! # Multiple Method Handlers
//! Similar to the single method handler macro but takes one or more arguments for the HTTP methods
//! it should respond to. See [route] macro docs.
//!
//! ```rust
//! # use actix_web::HttpResponse;
//! # use actix_web_codegen::route;
//! #[route("/test", method="GET", method="HEAD")]
//! async fn get_and_head_handler() -> HttpResponse {
//! HttpResponse::Ok().finish()
//! }
//! ```
//!
//! [actix-web attributes docs]: https://docs.rs/actix-web/*/actix_web/#attributes
//! [main]: attr.main.html
//! [route]: attr.route.html
//! [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
extern crate proc_macro; #![recursion_limit = "512"]
use proc_macro::TokenStream; use proc_macro::TokenStream;
@ -8,28 +66,27 @@ mod route;
/// Creates resource handler, allowing multiple HTTP method guards. /// Creates resource handler, allowing multiple HTTP method guards.
/// ///
/// ## Syntax /// # Syntax
/// ```text /// ```text
/// #[route("path", method="HTTP_METHOD"[, attributes])] /// #[route("path", method="HTTP_METHOD"[, attributes])]
/// ``` /// ```
/// ///
/// ### Attributes /// # Attributes
/// - `"path"` - Raw literal string with path for which to register handler. /// - `"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. /// - `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` /// - `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 /// # Example
/// ///
/// ```rust /// ```rust
/// 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("/", method="GET", method="HEAD")]
/// async fn example() -> HttpResponse { /// async fn example() -> HttpResponse {
/// HttpResponse::Ok().finish() /// HttpResponse::Ok().finish()
/// } /// }
@ -54,26 +111,25 @@ macro_rules! method_macro {
concat!(" concat!("
Creates route handler with `actix_web::guard::", stringify!($variant), "`. Creates route handler with `actix_web::guard::", stringify!($variant), "`.
## Syntax # Syntax
```text ```text
#[", stringify!($method), r#"("path"[, attributes])] #[", stringify!($method), r#"("path"[, attributes])]
``` ```
### Attributes # Attributes
- `"path"` - Raw literal string with path for which to register handler. - `"path"` - Raw literal string with path for which to register handler.
- `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 # Example
```rust ```rust
use actix_web::HttpResponse; # use actix_web::HttpResponse;
use actix_web_codegen::"#, stringify!($method), "; # use actix_web_codegen::"#, stringify!($method), ";
#[", stringify!($method), r#"("/")] #[", stringify!($method), r#"("/")]
async fn example() -> HttpResponse { async fn example() -> HttpResponse {
HttpResponse::Ok().finish() HttpResponse::Ok().finish()
@ -102,16 +158,17 @@ method_macro! {
/// Marks async main function as the actix system entry-point. /// Marks async main function as the actix system entry-point.
/// ///
/// ## Usage /// # Actix Web Re-export
/// This macro can be applied with `#[actix_web::main]` when used in Actix Web applications.
/// ///
/// # Usage
/// ```rust /// ```rust
/// #[actix_web::main] /// #[actix_web_codegen::main]
/// async fn main() { /// async fn main() {
/// async { println!("Hello world"); }.await /// async { println!("Hello world"); }.await
/// } /// }
/// ``` /// ```
#[proc_macro_attribute] #[proc_macro_attribute]
#[cfg(not(test))] // Work around for rust-lang/rust#62127
pub fn main(_: TokenStream, item: TokenStream) -> TokenStream { pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
use quote::quote; use quote::quote;

View File

@ -1,12 +1,14 @@
use actix_web::*; use actix_web_codegen::*;
#[route("/", method="GET", method="GET")] #[route("/", method="GET", method="GET")]
async fn index() -> impl Responder { async fn index() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test};
let srv = test::start(|| App::new().service(index)); let srv = test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");

View File

@ -5,7 +5,7 @@ error: HTTP method defined more than once: `GET`
| ^^^^^ | ^^^^^
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-duplicate-method-fail.rs:10:49 --> $DIR/route-duplicate-method-fail.rs:12:49
| |
10 | let srv = test::start(|| App::new().service(index)); 12 | let srv = test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -1,15 +0,0 @@
use actix_web::*;
#[route("/")]
async fn index() -> impl Responder {
HttpResponse::Ok()
}
#[actix_web::main]
async fn main() {
let srv = test::start(|| App::new().service(index));
let request = srv.get("/");
let response = request.send().await.unwrap();
assert!(response.status().is_success());
}

View File

@ -0,0 +1 @@
route-missing-method-fail.rs

View File

@ -5,7 +5,7 @@ error: The #[route(..)] macro requires at least one `method` attribute
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-missing-method-fail-msrv.rs:10:49 --> $DIR/route-missing-method-fail-msrv.rs:12:49
| |
10 | let srv = test::start(|| App::new().service(index)); 12 | let srv = test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -1,12 +1,14 @@
use actix_web::*; use actix_web_codegen::*;
#[route("/")] #[route("/")]
async fn index() -> impl Responder { async fn index() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test};
let srv = test::start(|| App::new().service(index)); let srv = test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");

View File

@ -7,7 +7,7 @@ error: The #[route(..)] macro requires at least one `method` attribute
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-missing-method-fail.rs:10:49 --> $DIR/route-missing-method-fail.rs:12:49
| |
10 | let srv = test::start(|| App::new().service(index)); 12 | let srv = test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -1,12 +1,14 @@
use actix_web::*; use actix_web_codegen::*;
#[route("/", method="GET", method="HEAD")] #[route("/", method="GET", method="HEAD")]
async fn index() -> impl Responder { async fn index() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test};
let srv = test::start(|| App::new().service(index)); let srv = test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");

View File

@ -1,12 +1,14 @@
use actix_web::*; use actix_web_codegen::*;
#[route("/", method="UNEXPECTED")] #[route("/", method="UNEXPECTED")]
async fn index() -> impl Responder { async fn index() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test};
let srv = test::start(|| App::new().service(index)); let srv = test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");

View File

@ -5,7 +5,7 @@ error: Unexpected HTTP method: `UNEXPECTED`
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-unexpected-method-fail.rs:10:49 --> $DIR/route-unexpected-method-fail.rs:12:49
| |
10 | let srv = test::start(|| App::new().service(index)); 12 | let srv = test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -1,30 +1,30 @@
use actix_web::*; use actix_web_codegen::*;
#[get("/one", other)] #[get("/one", other)]
async fn one() -> impl Responder { async fn one() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[post(/two)] #[post(/two)]
async fn two() -> impl Responder { async fn two() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
static PATCH_PATH: &str = "/three"; static PATCH_PATH: &str = "/three";
#[patch(PATCH_PATH)] #[patch(PATCH_PATH)]
async fn three() -> impl Responder { async fn three() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[delete("/four", "/five")] #[delete("/four", "/five")]
async fn four() -> impl Responder { async fn four() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
#[delete("/five", method="GET")] #[delete("/five", method="GET")]
async fn five() -> impl Responder { async fn five() -> String {
HttpResponse::Ok() "Hello World!".to_owned()
} }
fn main() {} fn main() {}

View File

@ -1,4 +1,5 @@
use actix_web::*; use actix_web::{Responder, HttpResponse, App, test};
use actix_web_codegen::*;
#[get("/config")] #[get("/config")]
async fn config() -> impl Responder { async fn config() -> impl Responder {