Skip to content

Commit

Permalink
prepare actix-web-lab release 0.16.1
Browse files Browse the repository at this point in the history
  • Loading branch information
robjtede committed Apr 23, 2022
1 parent b36d53b commit 7d97da1
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 58 deletions.
2 changes: 1 addition & 1 deletion actix-web-lab-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ syn = { version = "1", features = ["full", "parsing"] }
[dev-dependencies]
actix-test = "0.1.0-beta.13"
actix-web = "4.0.0"
actix-web-lab = "=0.16.0"
actix-web-lab = "=0.16.1"

futures-util = { version = "0.3.7", default-features = false, features = ["std"] }
trybuild = "1"
Expand Down
4 changes: 4 additions & 0 deletions actix-web-lab/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Changelog

## Unreleased - 2022-xx-xx


## 0.16.1 - 2022-04-23
- `Query` extractor now supports collecting multi-value items into a `Vec`.
- Add `derive` crate feature (on-by-default) that enables derive macros.


## 0.16.0 - 2022-04-11
Expand Down
12 changes: 7 additions & 5 deletions actix-web-lab/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "actix-web-lab"
version = "0.16.0"
version = "0.16.1"
description = "In-progress extractors and middleware for Actix Web"
authors = ["Rob Ede <robjtede@icloud.com>"]
keywords = ["actix", "http", "web", "framework", "async"]
Expand All @@ -20,17 +20,18 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
nightly = []
default = ["derive"]
derive = ["actix-web-lab-derive"]

[dependencies]
actix-web-lab-derive = { version = "=0.16.0", optional = true }

actix-web = { version = "4", default-features = false }
actix-http = "3"
actix-service = "2"
actix-router = "0.5"
actix-utils = "3"
actix-files = "0.6"

actix-web-lab-derive = "=0.16.0"
ahash = "0.7"
arc-swap = "1.1"
async-trait = "0.1"
Expand All @@ -54,8 +55,9 @@ tokio = { version = "1.13.1", features = ["sync", "macros"] }
tracing = { version = "0.1.30", features = ["log"] }

[dev-dependencies]
actix-web = { version = "4", features = ["rustls"] }
actix-web-lab-derive = "=0.16.0"

actix-web = { version = "4", features = ["rustls"] }
base64 = "0.13"
ed25519-dalek = "1.0.1"
env_logger = "0.9"
Expand Down
52 changes: 26 additions & 26 deletions actix-web-lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
> Experimental extractors, middleware, and other extras for possible inclusion in Actix Web.
[![crates.io](https://img.shields.io/crates/v/actix-web-lab?label=latest)](https://crates.io/crates/actix-web-lab)
[![Documentation](https://docs.rs/actix-web-lab/badge.svg)](https://docs.rs/actix-web-lab/0.16.0)
[![Documentation](https://docs.rs/actix-web-lab/badge.svg)](https://docs.rs/actix-web-lab/0.16.1)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web-lab.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-web-lab/0.16.0/status.svg)](https://deps.rs/crate/actix-web-lab/0.16.0)
[![dependency status](https://deps.rs/crate/actix-web-lab/0.16.1/status.svg)](https://deps.rs/crate/actix-web-lab/0.16.1)
[![Download](https://img.shields.io/crates/d/actix-web-lab.svg)](https://crates.io/crates/actix-web-lab)
[![CircleCI](https://circleci.com/gh/robjtede/actix-web-lab/tree/main.svg?style=shield)](https://circleci.com/gh/robjtede/actix-web-lab/tree/main)

Expand All @@ -16,54 +16,54 @@

### Responders

- `Csv`: efficient CSV streaming [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/respond/struct.Csv.html)
- `NdJson`: efficient NDJSON streaming [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/respond/struct.NdJson.html)
- `DisplayStream`: efficient line-by-line `Display` streaming [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/respond/struct.DisplayStream.html)
- `Html`: basic string wrapper that responds with HTML Content-Type [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/respond/struct.Html.html)
- `Csv`: efficient CSV streaming [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/respond/struct.Csv.html)
- `NdJson`: efficient NDJSON streaming [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/respond/struct.NdJson.html)
- `DisplayStream`: efficient line-by-line `Display` streaming [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/respond/struct.DisplayStream.html)
- `Html`: basic string wrapper that responds with HTML Content-Type [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/respond/struct.Html.html)

### Middleware

- `from_fn`: use an async function as a middleware [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/middleware/fn.from_fn.html)
- `RedirectHttps`: middleware to redirect traffic to HTTPS if connection is insecure with optional HSTS [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/middleware/struct.RedirectHttps.html)
- `redirect_to_www`: function middleware to redirect traffic to `www.` if not already there [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/middleware/fn.redirect_to_www.html)
- `ErrorHandlers`: alternative error handler middleware with simpler interface [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/middleware/struct.ErrorHandlers.html)
- `from_fn`: use an async function as a middleware [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/middleware/fn.from_fn.html)
- `RedirectHttps`: middleware to redirect traffic to HTTPS if connection is insecure with optional HSTS [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/middleware/struct.RedirectHttps.html)
- `redirect_to_www`: function middleware to redirect traffic to `www.` if not already there [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/middleware/fn.redirect_to_www.html)
- `ErrorHandlers`: alternative error handler middleware with simpler interface [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/middleware/struct.ErrorHandlers.html)

### Extractors

- `LazyData`: app data/state initialized on first use [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.LazyData.html)
- `SwapData`: app data/state that can be replaced at runtime (alternative to `Data<RwLock<T>>`) [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.SwapData.html)
- `LocalData`: app data/state that uses an `Rc` internally, avoiding atomic overhead (alternative to `Data<RwLock<T>>`) [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.DataSwap.html)
- `Json`: simplified JSON extractor with const-generic limits [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.Json.html)
- `Path`: simplified path parameter extractor that supports destructuring [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.Path.html)
- `Query`: simplified query-string extractor that can also collect multi-value items [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.Query.html)
- `RequestSignature`: wraps an extractor and calculates a request signature alongside [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/extract/struct.RequestSignature.html)
- `LazyData`: app data/state initialized on first use [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.LazyData.html)
- `SwapData`: app data/state that can be replaced at runtime (alternative to `Data<RwLock<T>>`) [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.SwapData.html)
- `LocalData`: app data/state that uses an `Rc` internally, avoiding atomic overhead (alternative to `Data<RwLock<T>>`) [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.DataSwap.html)
- `Json`: simplified JSON extractor with const-generic limits [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.Json.html)
- `Path`: simplified path parameter extractor that supports destructuring [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.Path.html)
- `Query`: simplified query-string extractor that can also collect multi-value items [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.Query.html)
- `RequestSignature`: wraps an extractor and calculates a request signature alongside [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/extract/struct.RequestSignature.html)

### Macros

- `FromRequest`: Derive macro to implement `FromRequest` on an aggregate struct of other extractors [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/derive.FromRequest.html)
- `FromRequest`: Derive macro to implement `FromRequest` on an aggregate struct of other extractors [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/derive.FromRequest.html)

### Headers

- `Hsts`: Strict-Transport-Security (HSTS) [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/header/struct.Hsts.html)
- `CacheControl`: Cache-Control header with support for modern directives [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/header/struct.CacheControl.html)
- `Hsts`: Strict-Transport-Security (HSTS) [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/header/struct.Hsts.html)
- `CacheControl`: Cache-Control header with support for modern directives [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/header/struct.CacheControl.html)

### Body Types

- `channel`: a simple channel-like body type with a sender side that can be used from another thread [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/body/fn.channel.html)
- `channel`: a simple channel-like body type with a sender side that can be used from another thread [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/body/fn.channel.html)

### Services

- `Redirect`: simple redirects [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/web/struct.Redirect.html)
- `spa`: Easy Single-page Application (SPA) service [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/web/fn.spa.html)
- `Redirect`: simple redirects [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/web/struct.Redirect.html)
- `spa`: Easy Single-page Application (SPA) service [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/web/fn.spa.html)

### Route Guards

- `Acceptable`: verifies that an `Accept` header is present and it contains a compatible MIME type [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/guard/struct.Acceptable.html)
- `Acceptable`: verifies that an `Accept` header is present and it contains a compatible MIME type [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/guard/struct.Acceptable.html)

### Test Utilities

- `test_request`: Construct `TestRequest` using an HTTP-like DSL [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/test/macro.assert_response_matches.html)
- `assert_response_matches`: quickly write tests that check various parts of a `ServiceResponse` [(docs)](https://docs.rs/actix-web-lab/0.16.0/actix_web_lab/test/macro.assert_response_matches.html)
- `test_request`: Construct `TestRequest` using an HTTP-like DSL [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/test/macro.assert_response_matches.html)
- `assert_response_matches`: quickly write tests that check various parts of a `ServiceResponse` [(docs)](https://docs.rs/actix-web-lab/0.16.1/actix_web_lab/test/macro.assert_response_matches.html)

## Things To Know About This Crate

Expand Down
53 changes: 27 additions & 26 deletions actix-web-lab/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,56 @@ use tracing::debug;

/// Extract typed information from the request's query.
///
/// This currently identical in purpose to the `Query` extractor in `actix-web` but it will be able
/// to track version bumps of `serde-urlencoded` more closely. This version also does away with the
/// custom error handler config.
///
/// To extract typed data from the URL query string, the inner type `T` must implement the
/// [`DeserializeOwned`] trait.
///
/// # Differences From `actix_web::web::Query`
/// This extractor uses `serde_html_form` under-the-hood which supports multi-value items. These are
/// sent by HTML select inputs when multiple options are chosen and can be collected into a `Vec`.
///
/// This version also removes the custom error handler config; users should instead prefer to handle
/// errors using the explicit `Result<Query<T>, E>` extractor in their handlers.
///
/// # Panics
/// A query string consists of unordered `key=value` pairs, therefore it cannot be decoded into any
/// type which depends upon data ordering (eg. tuples). Trying to do so will result in a panic.
///
/// # Examples
/// ```
/// use actix_web::get;
/// use actix_web::{get, Responder};
/// use actix_web_lab::extract::Query;
/// use serde::Deserialize;
///
/// #[derive(Debug, Deserialize)]
/// pub enum ResponseType {
/// Token,
/// Code
/// #[serde(rename_all = "lowercase")]
/// enum LogType {
/// Reports,
/// Actions,
/// }
///
/// #[derive(Debug, Deserialize)]
/// pub struct AuthRequest {
/// id: u64,
/// response_type: ResponseType,
/// }
/// pub struct LogsParams {
/// #[serde(rename = "type")]
/// log_type: u64,
///
/// // Deserialize `AuthRequest` struct from query string.
/// // This handler gets called only if the request's query parameters contain both fields.
/// // A valid request path for this handler would be `/?id=64&response_type=Code"`.
/// #[get("/")]
/// async fn index(info: Query<AuthRequest>) -> String {
/// format!("Authorization request for id={} and type={:?}!", info.id, info.response_type)
/// #[serde(rename = "user")]
/// users: Vec<String>,
/// }
///
/// // To access the entire underlying query struct, use `.into_inner()`.
/// #[get("/debug1")]
/// async fn debug1(info: Query<AuthRequest>) -> String {
/// dbg!("Authorization object = {:?}", info.into_inner());
/// "OK".to_string()
/// // Deserialize `LogsParams` struct from query string.
/// // This handler gets called only if the request's query parameters contain both fields.
/// // A valid request path for this handler would be `/logs?type=reports&user=foo&user=bar"`.
/// #[get("/logs")]
/// async fn index(info: Query<LogsParams>) -> impl Responder {
/// let LogsParams { log_type, users } = info.into_inner();
/// format!("Logs request for type={log_type} and user list={users:?}!")
/// }
///
/// // Or use destructuring, which is equivalent to `.into_inner()`.
/// #[get("/debug2")]
/// async fn debug2(Query(info): Query<AuthRequest>) -> String {
/// dbg!("Authorization object = {:?}", info);
/// "OK".to_string()
/// async fn debug2(Query(info): Query<LogsParams>) -> impl Responder {
/// dbg!("Authorization object = {info:?}");
/// "OK"
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
Expand Down

0 comments on commit 7d97da1

Please sign in to comment.