From 43c362779dabb6f021d42e345d214aaea043adf9 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 20 Jul 2020 17:40:58 +0100 Subject: [PATCH 1/3] also try extracting payload config as Data (#1610) --- CHANGES.md | 5 ++ src/types/payload.rs | 133 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 22 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index fca46d1c1..4b6697a7f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,10 +1,15 @@ # Changes ## Unreleased - 2020-xx-xx +### Changed +* `PayloadConfig` is now also considered in `Bytes` and `String` extractors when set + using `App::data`. [#1610] + ### Fixed * Memory leak of app data in pooled requests. [#1609] [#1609]: https://github.com/actix/actix-web/pull/1609 +[#1610]: https://github.com/actix/actix-web/pull/1610 ## 3.0.0-beta.1 - 2020-07-13 diff --git a/src/types/payload.rs b/src/types/payload.rs index 0efdc2c09..653abf089 100644 --- a/src/types/payload.rs +++ b/src/types/payload.rs @@ -13,10 +13,10 @@ use futures_util::future::{err, ok, Either, FutureExt, LocalBoxFuture, Ready}; use futures_util::StreamExt; use mime::Mime; -use crate::dev; use crate::extract::FromRequest; use crate::http::header; use crate::request::HttpRequest; +use crate::{dev, web}; /// Payload extractor returns request 's payload stream. /// @@ -142,13 +142,8 @@ impl FromRequest for Bytes { #[inline] fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future { - let tmp; - let cfg = if let Some(cfg) = req.app_data::() { - cfg - } else { - tmp = PayloadConfig::default(); - &tmp - }; + // allow both Config and Data + let cfg = PayloadConfig::from_req(req); if let Err(e) = cfg.check_mimetype(req) { return Either::Right(err(e)); @@ -197,13 +192,7 @@ impl FromRequest for String { #[inline] fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future { - let tmp; - let cfg = if let Some(cfg) = req.app_data::() { - cfg - } else { - tmp = PayloadConfig::default(); - &tmp - }; + let cfg = PayloadConfig::from_req(req); // check content-type if let Err(e) = cfg.check_mimetype(req) { @@ -237,7 +226,12 @@ impl FromRequest for String { ) } } -/// Payload configuration for request's payload. + +/// Configuration for request's payload. +/// +/// Applies to the built-in `Bytes` and `String` extractors. Note that the Payload extractor does +/// not automatically check conformance with this configuration to allow more flexibility when +/// building extractors on top of `Payload`. #[derive(Clone)] pub struct PayloadConfig { limit: usize, @@ -284,14 +278,28 @@ impl PayloadConfig { } Ok(()) } + + /// Allow payload config extraction from app data checking both `T` and `Data`, in that + /// order, and falling back to the default payload config. + fn from_req(req: &HttpRequest) -> &PayloadConfig { + req.app_data::() + .or_else(|| { + req.app_data::>() + .map(|d| d.as_ref()) + }) + .unwrap_or_else(|| &DEFAULT_PAYLOAD_CONFIG) + } } +// Allow shared refs to default. +static DEFAULT_PAYLOAD_CONFIG: PayloadConfig = PayloadConfig { + limit: 262_144, // 2^18 bytes (~256kB) + mimetype: None, +}; + impl Default for PayloadConfig { fn default() -> Self { - PayloadConfig { - limit: 262_144, - mimetype: None, - } + DEFAULT_PAYLOAD_CONFIG.clone() } } @@ -407,8 +415,9 @@ mod tests { use bytes::Bytes; use super::*; - use crate::http::header; - use crate::test::TestRequest; + use crate::http::{header, StatusCode}; + use crate::test::{call_service, init_service, TestRequest}; + use crate::{web, App, Responder}; #[actix_rt::test] async fn test_payload_config() { @@ -428,6 +437,86 @@ mod tests { assert!(cfg.check_mimetype(&req).is_ok()); } + #[actix_rt::test] + async fn test_config_recall_locations() { + async fn bytes_handler(_: Bytes) -> impl Responder { + "payload is probably json bytes" + } + + async fn string_handler(_: String) -> impl Responder { + "payload is probably json string" + } + + let mut srv = init_service( + App::new() + .service( + web::resource("/bytes-app-data") + .app_data( + PayloadConfig::default().mimetype(mime::APPLICATION_JSON), + ) + .route(web::get().to(bytes_handler)), + ) + .service( + web::resource("/bytes-data") + .data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON)) + .route(web::get().to(bytes_handler)), + ) + .service( + web::resource("/string-app-data") + .app_data( + PayloadConfig::default().mimetype(mime::APPLICATION_JSON), + ) + .route(web::get().to(string_handler)), + ) + .service( + web::resource("/string-data") + .data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON)) + .route(web::get().to(string_handler)), + ), + ) + .await; + + let req = TestRequest::with_uri("/bytes-app-data").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/bytes-data").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/string-app-data").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/string-data").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/bytes-app-data") + .header(header::CONTENT_TYPE, mime::APPLICATION_JSON) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/bytes-data") + .header(header::CONTENT_TYPE, mime::APPLICATION_JSON) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/string-app-data") + .header(header::CONTENT_TYPE, mime::APPLICATION_JSON) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/string-data") + .header(header::CONTENT_TYPE, mime::APPLICATION_JSON) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + } + #[actix_rt::test] async fn test_bytes() { let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11") From f8d5ad6b5349843d16ec391c711b7b05eddce428 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 21 Jul 2020 01:54:26 +0200 Subject: [PATCH 2/3] Make web::Path a tuple struct with a public inner value (#1594) Co-authored-by: Rob Ede --- CHANGES.md | 3 +++ MIGRATION.md | 20 +++++++++++++++++ README.md | 4 ++-- src/lib.rs | 4 ++-- src/types/path.rs | 57 +++++++++++++++++++++++------------------------ 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4b6697a7f..5783da75a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,13 @@ ### Changed * `PayloadConfig` is now also considered in `Bytes` and `String` extractors when set using `App::data`. [#1610] +* `web::Path` now has a public representation: `web::Path(pub T)` that enables + destructuring. [#1594] ### Fixed * Memory leak of app data in pooled requests. [#1609] +[#1594]: https://github.com/actix/actix-web/pull/1594 [#1609]: https://github.com/actix/actix-web/pull/1609 [#1610]: https://github.com/actix/actix-web/pull/1610 diff --git a/MIGRATION.md b/MIGRATION.md index d2e9735fb..7459b5b2d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -12,6 +12,26 @@ * `BodySize::Sized64` variant has been removed. `BodySize::Sized` now receives a `u64` instead of a `usize`. +* Code that was using `path.` to access a `web::Path<(A, B, C)>`s elements now needs to use + destructuring or `.into_inner()`. For example: + + ```rust + // Previously: + async fn some_route(path: web::Path<(String, String)>) -> String { + format!("Hello, {} {}", path.0, path.1) + } + + // Now (this also worked before): + async fn some_route(path: web::Path<(String, String)>) -> String { + let (first_name, last_name) = path.into_inner(); + format!("Hello, {} {}", first_name, last_name) + } + // Or (this wasn't previously supported): + async fn some_route(web::Path((first_name, last_name)): web::Path<(String, String)>) -> String { + format!("Hello, {} {}", first_name, last_name) + } + ``` + ## 2.0.0 * `HttpServer::start()` renamed to `HttpServer::run()`. It also possible to diff --git a/README.md b/README.md index 4d6bac29c..4f6a16199 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ Code: use actix_web::{get, web, App, HttpServer, Responder}; #[get("/{id}/{name}/index.html")] -async fn index(info: web::Path<(u32, String)>) -> impl Responder { - format!("Hello {}! id:{}", info.1, info.0) +async fn index(web::Path((id, name)): web::Path<(u32, String)>) -> impl Responder { + format!("Hello {}! id:{}", name, id) } #[actix_web::main] diff --git a/src/lib.rs b/src/lib.rs index eb46af664..8776a62b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,8 +9,8 @@ //! use actix_web::{get, web, App, HttpServer, Responder}; //! //! #[get("/{id}/{name}/index.html")] -//! async fn index(info: web::Path<(u32, String)>) -> impl Responder { -//! format!("Hello {}! id:{}", info.1, info.0) +//! async fn index(web::Path((id, name)): web::Path<(u32, String)>) -> impl Responder { +//! format!("Hello {}! id:{}", name, id) //! } //! //! #[actix_web::main] diff --git a/src/types/path.rs b/src/types/path.rs index 82050171c..dbb5f3ee0 100644 --- a/src/types/path.rs +++ b/src/types/path.rs @@ -25,8 +25,8 @@ use crate::FromRequest; /// /// extract path info from "/{username}/{count}/index.html" url /// /// {username} - deserializes to a String /// /// {count} - - deserializes to a u32 -/// async fn index(info: web::Path<(String, u32)>) -> String { -/// format!("Welcome {}! {}", info.0, info.1) +/// async fn index(web::Path((username, count)): web::Path<(String, u32)>) -> String { +/// format!("Welcome {}! {}", username, count) /// } /// /// fn main() { @@ -61,20 +61,18 @@ use crate::FromRequest; /// ); /// } /// ``` -pub struct Path { - inner: T, -} +pub struct Path(pub T); impl Path { /// Deconstruct to an inner value pub fn into_inner(self) -> T { - self.inner + self.0 } } impl AsRef for Path { fn as_ref(&self) -> &T { - &self.inner + &self.0 } } @@ -82,31 +80,31 @@ impl ops::Deref for Path { type Target = T; fn deref(&self) -> &T { - &self.inner + &self.0 } } impl ops::DerefMut for Path { fn deref_mut(&mut self) -> &mut T { - &mut self.inner + &mut self.0 } } impl From for Path { fn from(inner: T) -> Path { - Path { inner } + Path(inner) } } impl fmt::Debug for Path { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner.fmt(f) + self.0.fmt(f) } } impl fmt::Display for Path { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner.fmt(f) + self.0.fmt(f) } } @@ -120,8 +118,8 @@ impl fmt::Display for Path { /// /// extract path info from "/{username}/{count}/index.html" url /// /// {username} - deserializes to a String /// /// {count} - - deserializes to a u32 -/// async fn index(info: web::Path<(String, u32)>) -> String { -/// format!("Welcome {}! {}", info.0, info.1) +/// async fn index(web::Path((username, count)): web::Path<(String, u32)>) -> String { +/// format!("Welcome {}! {}", username, count) /// } /// /// fn main() { @@ -173,7 +171,7 @@ where ready( de::Deserialize::deserialize(PathDeserializer::new(req.match_info())) - .map(|inner| Path { inner }) + .map(Path) .map_err(move |e| { log::debug!( "Failed during Path extractor deserialization. \ @@ -290,21 +288,22 @@ mod tests { resource.match_path(req.match_info_mut()); let (req, mut pl) = req.into_parts(); - let res = <(Path<(String, String)>,)>::from_request(&req, &mut pl) + let (Path(res),) = <(Path<(String, String)>,)>::from_request(&req, &mut pl) .await .unwrap(); - assert_eq!((res.0).0, "name"); - assert_eq!((res.0).1, "user1"); + assert_eq!(res.0, "name"); + assert_eq!(res.1, "user1"); - let res = <(Path<(String, String)>, Path<(String, String)>)>::from_request( - &req, &mut pl, - ) - .await - .unwrap(); - assert_eq!((res.0).0, "name"); - assert_eq!((res.0).1, "user1"); - assert_eq!((res.1).0, "name"); - assert_eq!((res.1).1, "user1"); + let (Path(a), Path(b)) = + <(Path<(String, String)>, Path<(String, String)>)>::from_request( + &req, &mut pl, + ) + .await + .unwrap(); + assert_eq!(a.0, "name"); + assert_eq!(a.1, "user1"); + assert_eq!(b.0, "name"); + assert_eq!(b.1, "user1"); let () = <()>::from_request(&req, &mut pl).await.unwrap(); } @@ -329,7 +328,7 @@ mod tests { let s = s.into_inner(); assert_eq!(s.value, "user2"); - let s = Path::<(String, String)>::from_request(&req, &mut pl) + let Path(s) = Path::<(String, String)>::from_request(&req, &mut pl) .await .unwrap(); assert_eq!(s.0, "name"); @@ -344,7 +343,7 @@ mod tests { assert_eq!(s.as_ref().key, "name"); assert_eq!(s.value, 32); - let s = Path::<(String, u8)>::from_request(&req, &mut pl) + let Path(s) = Path::<(String, u8)>::from_request(&req, &mut pl) .await .unwrap(); assert_eq!(s.0, "name"); From 0ec335a39c660c89290a45e3d848d5e7c3ae5f02 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 21 Jul 2020 08:40:30 +0100 Subject: [PATCH 3/3] bump MSRV to 1.42 (#1616) --- .github/PULL_REQUEST_TEMPLATE.md | 6 ++++-- .github/workflows/linux.yml | 2 +- CHANGES.md | 1 + README.md | 4 ++-- actix-http/src/body.rs | 10 ++-------- actix-http/src/client/h2proto.rs | 5 +---- actix-http/src/h1/decoder.rs | 10 ++-------- actix-http/src/h1/dispatcher.rs | 10 ++-------- .../src/header/common/content_disposition.rs | 15 +++------------ actix-http/src/header/mod.rs | 5 +---- actix-http/src/ws/frame.rs | 5 +---- awc/src/response.rs | 11 +++-------- rust-toolchain | 2 +- src/types/form.rs | 15 +++------------ src/types/json.rs | 10 ++-------- 15 files changed, 29 insertions(+), 82 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index cc34e2bc6..1c0d467b1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,8 @@ -## PR Type -What kind of change does this PR make? + + +## PR Type + INSERT_PR_TYPE diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7529c8494..688db6cee 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: version: - - 1.41.1 # MSRV + - 1.42.0 # MSRV - stable - nightly diff --git a/CHANGES.md b/CHANGES.md index 5783da75a..d80e87946 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ using `App::data`. [#1610] * `web::Path` now has a public representation: `web::Path(pub T)` that enables destructuring. [#1594] +* MSRV is now 1.42.0. ### Fixed * Memory leak of app data in pooled requests. [#1609] diff --git a/README.md b/README.md index 4f6a16199..a42a1a6f8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![crates.io](https://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web) [![Documentation](https://docs.rs/actix-web/badge.svg)](https://docs.rs/actix-web) -[![Version](https://img.shields.io/badge/rustc-1.41+-lightgray.svg)](https://blog.rust-lang.org/2020/02/27/Rust-1.41.1.html) +[![Version](https://img.shields.io/badge/rustc-1.42+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html) ![License](https://img.shields.io/crates/l/actix-web.svg)
[![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) @@ -32,7 +32,7 @@ * Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) * Includes an async [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html) * Supports [Actix actor framework](https://github.com/actix/actix) -* Runs on stable Rust 1.41+ +* Runs on stable Rust 1.42+ ## Documentation diff --git a/actix-http/src/body.rs b/actix-http/src/body.rs index 0b01aa8ce..137f462a4 100644 --- a/actix-http/src/body.rs +++ b/actix-http/src/body.rs @@ -192,14 +192,8 @@ impl MessageBody for Body { impl PartialEq for Body { fn eq(&self, other: &Body) -> bool { match *self { - Body::None => match *other { - Body::None => true, - _ => false, - }, - Body::Empty => match *other { - Body::Empty => true, - _ => false, - }, + Body::None => matches!(*other, Body::None), + Body::Empty => matches!(*other, Body::Empty), Body::Bytes(ref b) => match *other { Body::Bytes(ref b2) => b == b2, _ => false, diff --git a/actix-http/src/client/h2proto.rs b/actix-http/src/client/h2proto.rs index 48ab9fe4a..7d1d3dc51 100644 --- a/actix-http/src/client/h2proto.rs +++ b/actix-http/src/client/h2proto.rs @@ -37,10 +37,7 @@ where trace!("Sending client request: {:?} {:?}", head, body.size()); let head_req = head.as_ref().method == Method::HEAD; let length = body.size(); - let eof = match length { - BodySize::None | BodySize::Empty | BodySize::Sized(0) => true, - _ => false, - }; + let eof = matches!(length, BodySize::None | BodySize::Empty | BodySize::Sized(0)); let mut req = Request::new(()); *req.uri_mut() = head.as_ref().uri.clone(); diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs index c9d3edf33..89a18aea9 100644 --- a/actix-http/src/h1/decoder.rs +++ b/actix-http/src/h1/decoder.rs @@ -655,10 +655,7 @@ mod tests { } fn is_unhandled(&self) -> bool { - match self { - PayloadType::Stream(_) => true, - _ => false, - } + matches!(self, PayloadType::Stream(_)) } } @@ -670,10 +667,7 @@ mod tests { } } fn eof(&self) -> bool { - match *self { - PayloadItem::Eof => true, - _ => false, - } + matches!(*self, PayloadItem::Eof) } } diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 51f107efb..a9ab29881 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -156,14 +156,8 @@ enum PollResponse { impl PartialEq for PollResponse { fn eq(&self, other: &PollResponse) -> bool { match self { - PollResponse::DrainWriteBuf => match other { - PollResponse::DrainWriteBuf => true, - _ => false, - }, - PollResponse::DoNothing => match other { - PollResponse::DoNothing => true, - _ => false, - }, + PollResponse::DrainWriteBuf => matches!(other, PollResponse::DrainWriteBuf), + PollResponse::DoNothing => matches!(other, PollResponse::DoNothing), _ => false, } } diff --git a/actix-http/src/header/common/content_disposition.rs b/actix-http/src/header/common/content_disposition.rs index d65933901..051dcfe80 100644 --- a/actix-http/src/header/common/content_disposition.rs +++ b/actix-http/src/header/common/content_disposition.rs @@ -387,26 +387,17 @@ impl ContentDisposition { /// Returns `true` if it is [`Inline`](DispositionType::Inline). pub fn is_inline(&self) -> bool { - match self.disposition { - DispositionType::Inline => true, - _ => false, - } + matches!(self.disposition, DispositionType::Inline) } /// Returns `true` if it is [`Attachment`](DispositionType::Attachment). pub fn is_attachment(&self) -> bool { - match self.disposition { - DispositionType::Attachment => true, - _ => false, - } + matches!(self.disposition, DispositionType::Attachment) } /// Returns `true` if it is [`FormData`](DispositionType::FormData). pub fn is_form_data(&self) -> bool { - match self.disposition { - DispositionType::FormData => true, - _ => false, - } + matches!(self.disposition, DispositionType::FormData) } /// Returns `true` if it is [`Ext`](DispositionType::Ext) and the `disp_type` matches. diff --git a/actix-http/src/header/mod.rs b/actix-http/src/header/mod.rs index 0db26ceb0..46fb31a62 100644 --- a/actix-http/src/header/mod.rs +++ b/actix-http/src/header/mod.rs @@ -148,10 +148,7 @@ impl ContentEncoding { #[inline] /// Is the content compressed? pub fn is_compression(self) -> bool { - match self { - ContentEncoding::Identity | ContentEncoding::Auto => false, - _ => true, - } + matches!(self, ContentEncoding::Identity | ContentEncoding::Auto) } #[inline] diff --git a/actix-http/src/ws/frame.rs b/actix-http/src/ws/frame.rs index 8f7004f18..0598a9b4e 100644 --- a/actix-http/src/ws/frame.rs +++ b/actix-http/src/ws/frame.rs @@ -229,10 +229,7 @@ mod tests { fn is_none( frm: &Result)>, ProtocolError>, ) -> bool { - match *frm { - Ok(None) => true, - _ => false, - } + matches!(*frm, Ok(None)) } fn extract( diff --git a/awc/src/response.rs b/awc/src/response.rs index ffc8c5408..d1490cb98 100644 --- a/awc/src/response.rs +++ b/awc/src/response.rs @@ -402,14 +402,9 @@ mod tests { fn json_eq(err: JsonPayloadError, other: JsonPayloadError) -> bool { match err { - JsonPayloadError::Payload(PayloadError::Overflow) => match other { - JsonPayloadError::Payload(PayloadError::Overflow) => true, - _ => false, - }, - JsonPayloadError::ContentType => match other { - JsonPayloadError::ContentType => true, - _ => false, - }, + JsonPayloadError::Payload(PayloadError::Overflow) => + matches!(other, JsonPayloadError::Payload(PayloadError::Overflow)), + JsonPayloadError::ContentType => matches!(other, JsonPayloadError::ContentType), _ => false, } } diff --git a/rust-toolchain b/rust-toolchain index f86fb9cbc..a50908ca3 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.41.1 +1.42.0 diff --git a/src/types/form.rs b/src/types/form.rs index c10ed4649..d7db595ca 100644 --- a/src/types/form.rs +++ b/src/types/form.rs @@ -407,18 +407,9 @@ mod tests { fn eq(err: UrlencodedError, other: UrlencodedError) -> bool { match err { - UrlencodedError::Overflow { .. } => match other { - UrlencodedError::Overflow { .. } => true, - _ => false, - }, - UrlencodedError::UnknownLength => match other { - UrlencodedError::UnknownLength => true, - _ => false, - }, - UrlencodedError::ContentType => match other { - UrlencodedError::ContentType => true, - _ => false, - }, + UrlencodedError::Overflow { .. } => matches!(other, UrlencodedError::Overflow { .. }), + UrlencodedError::UnknownLength => matches!(other, UrlencodedError::UnknownLength), + UrlencodedError::ContentType => matches!(other, UrlencodedError::ContentType), _ => false, } } diff --git a/src/types/json.rs b/src/types/json.rs index 6de9e0d86..1665ca95a 100644 --- a/src/types/json.rs +++ b/src/types/json.rs @@ -433,14 +433,8 @@ mod tests { fn json_eq(err: JsonPayloadError, other: JsonPayloadError) -> bool { match err { - JsonPayloadError::Overflow => match other { - JsonPayloadError::Overflow => true, - _ => false, - }, - JsonPayloadError::ContentType => match other { - JsonPayloadError::ContentType => true, - _ => false, - }, + JsonPayloadError::Overflow => matches!(other, JsonPayloadError::Overflow), + JsonPayloadError::ContentType => matches!(other, JsonPayloadError::ContentType), _ => false, } }