diff --git a/.cargo/config.toml b/.cargo/config.toml index 4425e0dda..deb300749 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,9 +6,12 @@ lint-all = "clippy --workspace --all-features --tests --examples --bins -- -Dcli ci-check-min = "hack --workspace check --no-default-features" ci-check-default = "hack --workspace check" ci-check-default-tests = "check --workspace --tests" -ci-check-all-feature-powerset="hack --workspace --feature-powerset --skip=__compress,io-uring check" +ci-check-all-feature-powerset="hack --workspace --feature-powerset --skip=__compress,experimental-io-uring check" ci-check-all-feature-powerset-linux="hack --workspace --feature-powerset --skip=__compress check" # testing ci-doctest-default = "test --workspace --doc --no-fail-fast -- --nocapture" ci-doctest = "test --workspace --all-features --doc --no-fail-fast -- --nocapture" + +# compile docs as docs.rs would +# RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc --no-deps --workspace diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index a7e0a0309..77918341a 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -1,6 +1,13 @@ # Changes ## Unreleased - 2021-xx-xx +### Added +- On-by-default `macros` feature flag to enable routing and runtime macros. [#2619] + +### Removed +- `rt::{Arbiter, ArbiterHandle}` re-exports. [#2619] + +[#2601]: https://github.com/actix/actix-web/pull/2601 ## 4.0.0-rc.1 - 2022-01-31 diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 4e10dce18..92c303b5c 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -20,7 +20,7 @@ edition = "2018" [package.metadata.docs.rs] # features that docs.rs will build with -features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "secure-cookies"] +features = ["macros", "openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "secure-cookies"] rustdoc-args = ["--cfg", "docsrs"] [lib] @@ -28,7 +28,7 @@ name = "actix_web" path = "src/lib.rs" [features] -default = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"] +default = ["macros", "compress-brotli", "compress-gzip", "compress-zstd", "cookies"] # Brotli algorithm content-encoding support compress-brotli = ["actix-http/compress-brotli", "__compress"] @@ -37,16 +37,23 @@ compress-gzip = ["actix-http/compress-gzip", "__compress"] # Zstd algorithm content-encoding support compress-zstd = ["actix-http/compress-zstd", "__compress"] -# support for cookies +# Routing and runtime proc macros +macros = [ + "actix-rt/macros", + "actix-macros", + "actix-web-codegen", +] + +# Cookies support cookies = ["cookie"] -# secure cookies feature -secure-cookies = ["cookie/secure"] +# Secure & signed cookies +secure-cookies = ["cookies", "cookie/secure"] -# openssl +# TLS via OpenSSL openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] -# rustls +# TLS via Rustls rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] # Internal (PRIVATE!) features used to aid testing and checking feature status. @@ -58,16 +65,16 @@ experimental-io-uring = ["actix-server/io-uring"] [dependencies] actix-codec = "0.4.1" -actix-macros = "0.2.3" -actix-rt = "2.6" +actix-macros = { version = "0.2.3", optional = true } +actix-rt = { version = "2.6", default-features = false } actix-server = "2" -actix-service = "2.0.0" -actix-utils = "3.0.0" -actix-tls = { version = "3.0.0", default-features = false, optional = true } +actix-service = "2" +actix-utils = "3" +actix-tls = { version = "3", default-features = false, optional = true } actix-http = { version = "3.0.0-rc.1", features = ["http2", "ws"] } actix-router = "0.5.0-rc.3" -actix-web-codegen = "0.5.0-rc.2" +actix-web-codegen = { version = "0.5.0-rc.2", optional = true } ahash = "0.7" bytes = "1" @@ -84,7 +91,7 @@ log = "0.4" mime = "0.3" pin-project-lite = "0.2.7" regex = "1.4" -serde = { version = "1.0", features = ["derive"] } +serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" smallvec = "1.6.1" @@ -106,6 +113,7 @@ futures-util = { version = "0.3.7", default-features = false, features = ["std"] rand = "0.8" rcgen = "0.8" rustls-pemfile = "0.2" +serde = { version = "1.0", features = ["derive"] } static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.9" } tls-rustls = { package = "rustls", version = "0.20.0" } diff --git a/actix-web/examples/macroless.rs b/actix-web/examples/macroless.rs new file mode 100644 index 000000000..78ffd45c1 --- /dev/null +++ b/actix-web/examples/macroless.rs @@ -0,0 +1,21 @@ +use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer}; + +async fn index(req: HttpRequest) -> &'static str { + println!("REQ: {:?}", req); + "Hello world!\r\n" +} + +fn main() -> std::io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + rt::System::new().block_on( + HttpServer::new(|| { + App::new() + .wrap(middleware::Logger::default()) + .service(web::resource("/").route(web::get().to(index))) + }) + .bind(("127.0.0.1", 8080))? + .workers(1) + .run(), + ) +} diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index a63cf5d50..be3526393 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -21,8 +21,7 @@ use crate::{ }, }; -/// Application builder - structure that follows the builder pattern -/// for building application instances. +/// The top-level builder for an Actix Web application. pub struct App { endpoint: T, services: Vec>, diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs index 18f0d581d..c3313db81 100644 --- a/actix-web/src/lib.rs +++ b/actix-web/src/lib.rs @@ -57,6 +57,7 @@ //! //! # Crate Features //! * `cookies` - cookies support (enabled by default) +//! * `macros` - routing and runtime macros (enabled by default) //! * `compress-brotli` - brotli content encoding compression support (enabled by default) //! * `compress-gzip` - gzip and deflate content encoding compression support (enabled by default) //! * `compress-zstd` - zstd content encoding compression support (enabled by default) @@ -68,6 +69,7 @@ #![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] +#![cfg_attr(docsrs, feature(doc_cfg))] mod app; mod app_service; @@ -88,6 +90,7 @@ mod resource; mod response; mod rmap; mod route; +pub mod rt; mod scope; mod server; mod service; @@ -95,15 +98,10 @@ pub mod test; pub(crate) mod types; pub mod web; -pub use actix_http::{body, HttpMessage}; -#[doc(inline)] -pub use actix_rt as rt; -pub use actix_web_codegen::*; -#[cfg(feature = "cookies")] -pub use cookie; - pub use crate::app::App; -pub use crate::error::{Error, ResponseError, Result}; +#[doc(inline)] +pub use crate::error::Result; +pub use crate::error::{Error, ResponseError}; pub use crate::extract::FromRequest; pub use crate::handler::Handler; pub use crate::request::HttpRequest; @@ -114,4 +112,32 @@ pub use crate::scope::Scope; pub use crate::server::HttpServer; pub use crate::types::Either; +pub use actix_http::{body, HttpMessage}; + +#[cfg(feature = "cookies")] +#[cfg_attr(docsrs, doc(cfg(feature = "cookies")))] +#[doc(inline)] +pub use cookie; + +macro_rules! codegen_reexport { + ($name:ident) => { + #[cfg(feature = "macros")] + #[cfg_attr(docsrs, doc(cfg(feature = "macros")))] + pub use actix_web_codegen::$name; + }; +} + +codegen_reexport!(main); +codegen_reexport!(test); +codegen_reexport!(route); +codegen_reexport!(head); +codegen_reexport!(get); +codegen_reexport!(post); +codegen_reexport!(patch); +codegen_reexport!(put); +codegen_reexport!(delete); +codegen_reexport!(trace); +codegen_reexport!(connect); +codegen_reexport!(options); + pub(crate) type BoxError = Box; diff --git a/actix-web/src/rt.rs b/actix-web/src/rt.rs new file mode 100644 index 000000000..87d76048f --- /dev/null +++ b/actix-web/src/rt.rs @@ -0,0 +1,38 @@ +//! A selection of re-exports from [`actix-rt`] and [`tokio`]. +//! +//! [`actix-rt`]: https://docs.rs/actix_rt +//! [`tokio`]: https://docs.rs/tokio +//! +//! # Running Actix Web Macro-less +//! ```no_run +//! use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer}; +//! +//! async fn index(req: HttpRequest) -> &'static str { +//! println!("REQ: {:?}", req); +//! "Hello world!\r\n" +//! } +//! +//! # fn main() -> std::io::Result<()> { +//! rt::System::new().block_on( +//! HttpServer::new(|| { +//! App::new() +//! .wrap(middleware::Logger::default()) +//! .service(web::resource("/").route(web::get().to(index))) +//! }) +//! .bind(("127.0.0.1", 8080))? +//! .workers(1) +//! .run() +//! ) +//! # } +//! ``` + +// In particular: +// - Omit the `Arbiter` types because they have limited value here. +// - Re-export but hide the runtime macros because they won't work directly but are required for +// `#[actix_web::main]` and `#[actix_web::test]` to work. + +pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner}; + +#[cfg(feature = "macros")] +#[doc(hidden)] +pub use actix_rt::{main, test}; diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index 061c3e044..3843abcf8 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -610,11 +610,10 @@ where } } -/// Macro helping register different types of services at the sametime. +/// Macro to help register different types of services at the same time. /// -/// The service type must be implementing [`HttpServiceFactory`](self::HttpServiceFactory) trait. -/// -/// The max number of services can be grouped together is 12. +/// The max number of services that can be grouped together is 12 and all must implement the +/// [`HttpServiceFactory`] trait. /// /// # Examples /// ```