From 09d46bd7786096ec27400963c7e65127e8927088 Mon Sep 17 00:00:00 2001 From: Omid Rad Date: Tue, 21 Mar 2023 13:54:10 +0100 Subject: [PATCH] Update deps + clippy + typos --- Cargo.toml | 9 ++-- src/auth/authorization.rs | 8 +-- src/auth/basic_auth.rs | 13 ++--- src/auth/www_authenticate.rs | 13 ++--- src/body.rs | 14 +++-- src/cache/age.rs | 8 +-- src/cache/cache_control/cache_control.rs | 13 +++-- src/cache/cache_control/cache_directive.rs | 23 ++++++-- src/cache/cache_control/mod.rs | 2 +- src/cache/clear_site_data/directive.rs | 1 + src/cache/clear_site_data/mod.rs | 14 ++--- src/cache/expires.rs | 8 +-- src/conditional/etag.rs | 27 +++++----- src/conditional/if_match.rs | 18 +++---- src/conditional/if_modified_since.rs | 7 ++- src/conditional/if_none_match.rs | 18 +++---- src/conditional/if_unmodified_since.rs | 7 ++- src/conditional/last_modified.rs | 7 ++- src/conditional/vary.rs | 18 +++---- src/content/accept.rs | 22 ++++---- src/content/accept_encoding.rs | 22 ++++---- src/content/content_encoding.rs | 7 ++- src/content/content_length.rs | 7 ++- src/content/content_location.rs | 14 ++--- src/content/content_type.rs | 5 +- src/content/encoding_proposal.rs | 11 ++-- src/content/media_type_proposal.rs | 8 +-- src/error.rs | 13 +++-- src/extensions.rs | 14 ++--- src/headers/header_name.rs | 8 +-- src/headers/header_value.rs | 10 ++-- src/headers/header_values.rs | 10 ++-- src/headers/headers.rs | 7 ++- src/headers/values.rs | 15 ++---- src/hyperium_http.rs | 26 +++++---- src/method.rs | 1 + src/mime/mod.rs | 14 ++--- src/mime/parse.rs | 19 ++++--- src/other/date.rs | 9 ++-- src/other/expect.rs | 6 +-- src/other/referer.rs | 7 ++- src/other/retry_after.rs | 15 +++--- src/other/source_map.rs | 7 ++- src/parse_utils.rs | 4 +- src/proxies/forwarded.rs | 46 +++++++++------- src/request.rs | 43 ++++++++++----- src/response.rs | 29 +++++++--- src/security/csp.rs | 9 ++-- src/security/strict_transport_security.rs | 39 +++++++------- src/security/timing_allow_origin.rs | 14 ++--- src/server/allow.rs | 12 ++--- src/status.rs | 26 ++++----- src/status_code.rs | 8 ++- src/trace/server_timing/metric.rs | 7 ++- src/trace/server_timing/mod.rs | 11 ++-- src/trace/server_timing/parse.rs | 2 +- src/trace/trace_context.rs | 46 ++++++++-------- src/trailers.rs | 5 ++ src/transfer/encoding_proposal.rs | 11 ++-- src/transfer/te.rs | 22 ++++---- src/transfer/transfer_encoding.rs | 7 ++- src/upgrade/sender.rs | 1 + src/utils/date.rs | 62 +++++++++++----------- src/utils/mod.rs | 17 +++--- src/version.rs | 2 +- tests/error.rs | 11 ++-- 66 files changed, 509 insertions(+), 430 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 42cc51ab..bd2614b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,10 +28,10 @@ serde = ["serde_qs", "serde_crate", "serde_json", "serde_urlencoded", "url/serde [dependencies] fastrand = "1.4.0" -base64 = "0.13.0" +base64 = "0.21.0" futures-lite = "1.11.1" async-channel = "1.5.1" -infer = "0.7.0" +infer = "0.13.0" pin-project-lite = "0.2.0" url = "2.1.1" anyhow = "1.0.26" @@ -43,14 +43,13 @@ async-std = { version = "1.6.0", optional = true } http = { version = "0.2.0", optional = true } # features: cookies -cookie = { version = "0.16.0", features = ["percent-encode"], optional = true } +cookie = { version = "0.17.0", features = ["percent-encode"], optional = true } # features: serde serde_json = { version = "1.0.51", optional = true } serde_crate = { version = "1.0.106", features = ["derive"], optional = true, package = "serde" } serde_urlencoded = { version = "0.7.0", optional = true} -serde_qs = { version = "0.9.1", optional = true } - +serde_qs = { version = "0.12.0", optional = true } [dev-dependencies] http = "0.2.0" diff --git a/src/auth/authorization.rs b/src/auth/authorization.rs index cf2f2ddb..b5071a91 100644 --- a/src/auth/authorization.rs +++ b/src/auth/authorization.rs @@ -38,6 +38,7 @@ pub struct Authorization { impl Authorization { /// Create a new instance of `Authorization`. + #[must_use] pub fn new(scheme: AuthenticationScheme, credentials: String) -> Self { Self { scheme, @@ -47,10 +48,7 @@ impl Authorization { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(AUTHORIZATION) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(AUTHORIZATION) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -72,6 +70,7 @@ impl Authorization { } /// Get the authorization scheme. + #[must_use] pub fn scheme(&self) -> AuthenticationScheme { self.scheme } @@ -82,6 +81,7 @@ impl Authorization { } /// Get the authorization credentials. + #[must_use] pub fn credentials(&self) -> &str { self.credentials.as_str() } diff --git a/src/auth/basic_auth.rs b/src/auth/basic_auth.rs index 664cfcb5..c901c0a3 100644 --- a/src/auth/basic_auth.rs +++ b/src/auth/basic_auth.rs @@ -5,6 +5,7 @@ use crate::{ headers::Header, }; use crate::{bail_status as bail, ensure_status as ensure}; +use base64::{engine::general_purpose, Engine}; /// HTTP Basic authorization. /// @@ -54,10 +55,7 @@ impl BasicAuth { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let auth = match Authorization::from_headers(headers)? { - Some(auth) => auth, - None => return Ok(None), - }; + let Some(auth) = Authorization::from_headers(headers)? else { return Ok(None) }; let scheme = auth.scheme(); ensure!( @@ -71,7 +69,7 @@ impl BasicAuth { /// Create a new instance from the base64 encoded credentials. pub fn from_credentials(credentials: impl AsRef<[u8]>) -> crate::Result { - let bytes = base64::decode(credentials).status(400)?; + let bytes = general_purpose::STANDARD.decode(credentials).status(400)?; let credentials = String::from_utf8(bytes).status(400)?; let mut iter = credentials.splitn(2, ':'); @@ -88,11 +86,13 @@ impl BasicAuth { } /// Get the username. + #[must_use] pub fn username(&self) -> &str { self.username.as_str() } /// Get the password. + #[must_use] pub fn password(&self) -> &str { self.password.as_str() } @@ -105,7 +105,8 @@ impl Header for BasicAuth { fn header_value(&self) -> HeaderValue { let scheme = AuthenticationScheme::Basic; - let credentials = base64::encode(format!("{}:{}", self.username, self.password)); + let credentials = + general_purpose::STANDARD.encode(format!("{}:{}", self.username, self.password)); let auth = Authorization::new(scheme, credentials); auth.header_value() } diff --git a/src/auth/www_authenticate.rs b/src/auth/www_authenticate.rs index bf9d7a05..667fffaa 100644 --- a/src/auth/www_authenticate.rs +++ b/src/auth/www_authenticate.rs @@ -44,16 +44,14 @@ pub struct WwwAuthenticate { impl WwwAuthenticate { /// Create a new instance of `WwwAuthenticate`. + #[must_use] pub fn new(scheme: AuthenticationScheme, realm: String) -> Self { Self { scheme, realm } } /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(WWW_AUTHENTICATE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(WWW_AUTHENTICATE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -69,10 +67,7 @@ impl WwwAuthenticate { }; let realm = realm.trim_start(); - let realm = match realm.strip_prefix(r#"realm=""#) { - Some(realm) => realm, - None => bail!(400, "realm not found"), - }; + let Some(realm) = realm.strip_prefix(r#"realm=""#) else { bail!(400, "realm not found") }; let mut chars = realm.chars(); let mut closing_quote = false; @@ -94,6 +89,7 @@ impl WwwAuthenticate { } /// Get the authorization scheme. + #[must_use] pub fn scheme(&self) -> AuthenticationScheme { self.scheme } @@ -104,6 +100,7 @@ impl WwwAuthenticate { } /// Get the authorization realm. + #[must_use] pub fn realm(&self) -> &str { self.realm.as_str() } diff --git a/src/body.rs b/src/body.rs index ac1acfc7..08842446 100644 --- a/src/body.rs +++ b/src/body.rs @@ -76,6 +76,7 @@ impl Body { /// let mut req = Response::new(StatusCode::Ok); /// req.set_body(Body::empty()); /// ``` + #[must_use] pub fn empty() -> Self { Self { reader: Box::new(io::empty()), @@ -129,6 +130,7 @@ impl Body { /// let body = Body::from_reader(cursor, None); /// let _ = body.into_reader(); /// ``` + #[must_use] pub fn into_reader(self) -> Box { self.reader } @@ -151,6 +153,7 @@ impl Body { /// let input = vec![1, 2, 3]; /// req.set_body(Body::from_bytes(input)); /// ``` + #[must_use] pub fn from_bytes(bytes: Vec) -> Self { Self { mime: Some(mime::BYTE_STREAM), @@ -201,6 +204,7 @@ impl Body { /// let input = String::from("hello Nori!"); /// req.set_body(Body::from_string(input)); /// ``` + #[must_use] pub fn from_string(s: String) -> Self { Self { mime: Some(mime::PLAIN), @@ -464,16 +468,19 @@ impl Body { /// let body = Body::from_reader(cursor, Some(len)); /// assert_eq!(body.len(), Some(10)); /// ``` + #[must_use] pub fn len(&self) -> Option { self.length } /// Returns `true` if the body has a length of zero, and `false` otherwise. + #[must_use] pub fn is_empty(&self) -> Option { self.length.map(|length| length == 0) } /// Returns the mime type of this Body. + #[must_use] pub fn mime(&self) -> Option<&Mime> { self.mime.as_ref() } @@ -517,6 +524,7 @@ impl Body { /// assert_eq!(&body.into_string().await.unwrap(), "Hello Nori"); /// # Ok(()) }) } /// ``` + #[must_use] pub fn chain(self, other: Body) -> Self { let mime = if self.mime == other.mime { self.mime.clone() @@ -530,7 +538,7 @@ impl Body { Self { mime, length, - reader: Box::new(futures_lite::io::AsyncReadExt::chain(self, other)), + reader: Box::new(io::AsyncReadExt::chain(self, other)), bytes_read: 0, } } @@ -608,7 +616,7 @@ impl AsyncBufRead for Body { } fn consume(mut self: Pin<&mut Self>, amt: usize) { - Pin::new(&mut self.reader).consume(amt) + Pin::new(&mut self.reader).consume(amt); } } @@ -630,7 +638,7 @@ async fn peek_mime(file: &mut async_std::fs::File) -> io::Result> { /// This is useful for plain-text formats such as HTML and CSS. #[cfg(all(feature = "fs", not(target_os = "unknown")))] fn guess_ext(path: &std::path::Path) -> Option { - let ext = path.extension().and_then(|p| p.to_str()); + let ext = path.extension().and_then(std::ffi::OsStr::to_str); ext.and_then(Mime::from_extension) } diff --git a/src/cache/age.rs b/src/cache/age.rs index 0ee78a00..b41a1018 100644 --- a/src/cache/age.rs +++ b/src/cache/age.rs @@ -36,27 +36,27 @@ pub struct Age { impl Age { /// Create a new instance of `Age`. + #[must_use] pub fn new(dur: Duration) -> Self { Self { dur } } /// Create a new instance of `Age` from secs. + #[must_use] pub fn from_secs(secs: u64) -> Self { let dur = Duration::from_secs(secs); Self { dur } } /// Get the duration from the header. + #[must_use] pub fn duration(&self) -> Duration { self.dur } /// Create an instance of `Age` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(AGE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(AGE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/cache/cache_control/cache_control.rs b/src/cache/cache_control/cache_control.rs index deffd6bd..400432b8 100644 --- a/src/cache/cache_control/cache_control.rs +++ b/src/cache/cache_control/cache_control.rs @@ -37,6 +37,7 @@ pub struct CacheControl { impl CacheControl { /// Create a new instance of `CacheControl`. + #[must_use] pub fn new() -> Self { Self { entries: vec![] } } @@ -44,15 +45,12 @@ impl CacheControl { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(CACHE_CONTROL) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(CACHE_CONTROL) else { return Ok(None) }; for value in headers { for part in value.as_str().trim().split(',') { // Try and parse a directive from a str. If the directive is - // unkown we skip it. + // unknown we skip it. if let Some(entry) = CacheDirective::from_str(part)? { entries.push(entry); } @@ -67,6 +65,7 @@ impl CacheControl { } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -90,8 +89,8 @@ impl Header for CacheControl { for (n, directive) in self.entries.iter().enumerate() { let directive: HeaderValue = directive.clone().into(); match n { - 0 => write!(output, "{}", directive).unwrap(), - _ => write!(output, ", {}", directive).unwrap(), + 0 => write!(output, "{directive}").unwrap(), + _ => write!(output, ", {directive}").unwrap(), }; } diff --git a/src/cache/cache_control/cache_directive.rs b/src/cache/cache_control/cache_directive.rs index 5e8b0b98..14c4c8e0 100644 --- a/src/cache/cache_control/cache_directive.rs +++ b/src/cache/cache_control/cache_directive.rs @@ -45,8 +45,11 @@ pub enum CacheDirective { impl CacheDirective { /// Check whether this directive is valid in an HTTP request. + #[must_use] pub fn valid_in_req(&self) -> bool { - use CacheDirective::*; + use CacheDirective::{ + MaxAge, MaxStale, MinFresh, NoCache, NoStore, NoTransform, OnlyIfCached, + }; matches!( self, MaxAge(_) | MaxStale(_) | MinFresh(_) | NoCache | NoStore | NoTransform | OnlyIfCached @@ -54,8 +57,12 @@ impl CacheDirective { } /// Check whether this directive is valid in an HTTP response. + #[must_use] pub fn valid_in_res(&self) -> bool { - use CacheDirective::*; + use CacheDirective::{ + MaxAge, MustRevalidate, NoCache, NoStore, NoTransform, Private, ProxyRevalidate, + Public, SMaxAge, StaleIfError, StaleWhileRevalidate, + }; matches!( self, MustRevalidate @@ -79,7 +86,11 @@ impl CacheDirective { // function, but we cannot guarantee this to be true in the general // sense. pub(crate) fn from_str(s: &str) -> crate::Result> { - use CacheDirective::*; + use CacheDirective::{ + Immutable, MaxAge, MaxStale, MinFresh, MustRevalidate, NoCache, NoStore, NoTransform, + OnlyIfCached, Private, ProxyRevalidate, Public, SMaxAge, StaleIfError, + StaleWhileRevalidate, + }; let s = s.trim(); @@ -129,7 +140,11 @@ impl CacheDirective { impl From for HeaderValue { fn from(directive: CacheDirective) -> Self { - use CacheDirective::*; + use CacheDirective::{ + Immutable, MaxAge, MaxStale, MinFresh, MustRevalidate, NoCache, NoStore, NoTransform, + OnlyIfCached, Private, ProxyRevalidate, Public, SMaxAge, StaleIfError, + StaleWhileRevalidate, + }; let h = |s: String| unsafe { HeaderValue::from_bytes_unchecked(s.into_bytes()) }; match directive { diff --git a/src/cache/cache_control/mod.rs b/src/cache/cache_control/mod.rs index f9150363..c99ef2ba 100644 --- a/src/cache/cache_control/mod.rs +++ b/src/cache/cache_control/mod.rs @@ -35,7 +35,7 @@ mod test { } #[test] - fn ignore_unkonwn_directives() -> crate::Result<()> { + fn ignore_unknown_directives() -> crate::Result<()> { let mut headers = Headers::new(); headers.insert(CACHE_CONTROL, "barrel_roll").unwrap(); let entries = CacheControl::from_headers(headers)?.unwrap(); diff --git a/src/cache/clear_site_data/directive.rs b/src/cache/clear_site_data/directive.rs index b178027e..a614f42b 100644 --- a/src/cache/clear_site_data/directive.rs +++ b/src/cache/clear_site_data/directive.rs @@ -28,6 +28,7 @@ pub enum ClearDirective { impl ClearDirective { /// Get the formatted string. + #[must_use] pub fn as_str(&self) -> &'static str { match self { ClearDirective::Cache => r#""cache""#, diff --git a/src/cache/clear_site_data/mod.rs b/src/cache/clear_site_data/mod.rs index bb38ab80..e3105bde 100644 --- a/src/cache/clear_site_data/mod.rs +++ b/src/cache/clear_site_data/mod.rs @@ -52,6 +52,7 @@ pub struct ClearSiteData { impl ClearSiteData { /// Create a new instance of `ClearSiteData`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -62,10 +63,7 @@ impl ClearSiteData { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let header_values = match headers.as_ref().get(CLEAR_SITE_DATA) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(header_values) = headers.as_ref().get(CLEAR_SITE_DATA) else { return Ok(None) }; let mut wildcard = false; for value in header_values { @@ -88,16 +86,18 @@ impl ClearSiteData { } /// Returns `true` if a wildcard directive was set. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -220,8 +220,8 @@ impl Header for ClearSiteData { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { - 0 => write!(output, "{}", etag).unwrap(), - _ => write!(output, ", {}", etag).unwrap(), + 0 => write!(output, "{etag}").unwrap(), + _ => write!(output, ", {etag}").unwrap(), }; } diff --git a/src/cache/expires.rs b/src/cache/expires.rs index 89c4e6f4..222fa606 100644 --- a/src/cache/expires.rs +++ b/src/cache/expires.rs @@ -40,27 +40,27 @@ pub struct Expires { impl Expires { /// Create a new instance of `Expires`. + #[must_use] pub fn new(dur: Duration) -> Self { let instant = SystemTime::now() + dur; Self { instant } } /// Create a new instance of `Expires` from secs. + #[must_use] pub fn new_at(instant: SystemTime) -> Self { Self { instant } } /// Get the expiration time. + #[must_use] pub fn expiration(&self) -> SystemTime { self.instant } /// Create an instance of `Expires` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(EXPIRES) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(EXPIRES) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/conditional/etag.rs b/src/conditional/etag.rs index c7245f86..d70787e5 100644 --- a/src/conditional/etag.rs +++ b/src/conditional/etag.rs @@ -5,7 +5,7 @@ use std::fmt::{self, Debug, Display}; /// HTTP Entity Tags. /// -/// ETags provide an ID for a particular resource, enabling clients and servers +/// `ETags` provide an ID for a particular resource, enabling clients and servers /// to reason about caches and make conditional requests. /// /// # Specifications @@ -39,13 +39,15 @@ pub enum ETag { } impl ETag { - /// Create a new ETag that uses strong validation. + /// Create a new `ETag` that uses strong validation. + #[must_use] pub fn new(s: String) -> Self { debug_assert!(!s.contains('\\'), "ETags ought to avoid backslash chars"); Self::Strong(s) } - /// Create a new ETag that uses weak validation. + /// Create a new `ETag` that uses weak validation. + #[must_use] pub fn new_weak(s: String) -> Self { debug_assert!(!s.contains('\\'), "ETags ought to avoid backslash chars"); Self::Weak(s) @@ -53,25 +55,24 @@ impl ETag { /// Create a new instance from headers. /// - /// Only a single ETag per resource is assumed to exist. If multiple ETag + /// Only a single `ETag` per resource is assumed to exist. If multiple `ETag` /// headers are found the last one is used. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(ETAG) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(ETAG) else { return Ok(None) }; // If a header is returned we can assume at least one exists. let s = headers.iter().last().unwrap().as_str(); Self::from_str(s).map(Some) } - /// Returns `true` if the ETag is a `Strong` value. + /// Returns `true` if the `ETag` is a `Strong` value. + #[must_use] pub fn is_strong(&self) -> bool { matches!(self, Self::Strong(_)) } - /// Returns `true` if the ETag is a `Weak` value. + /// Returns `true` if the `ETag` is a `Weak` value. + #[must_use] pub fn is_weak(&self) -> bool { matches!(self, Self::Weak(_)) } @@ -126,8 +127,8 @@ impl Header for ETag { impl Display for ETag { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::Strong(s) => write!(f, r#""{}""#, s), - Self::Weak(s) => write!(f, r#"W/"{}""#, s), + Self::Strong(s) => write!(f, r#""{s}""#), + Self::Weak(s) => write!(f, r#"W/"{s}""#), } } } @@ -181,7 +182,7 @@ mod test { let mut headers = Headers::new(); headers.insert(ETAG, s).unwrap(); let err = ETag::from_headers(headers).unwrap_err(); - assert_eq!(format!("{}", err), msg); + assert_eq!(format!("{err}"), msg); } #[test] diff --git a/src/conditional/if_match.rs b/src/conditional/if_match.rs index 5f84c2bd..fca663ed 100644 --- a/src/conditional/if_match.rs +++ b/src/conditional/if_match.rs @@ -1,4 +1,4 @@ -//! Apply the HTTP method if the ETag matches. +//! Apply the HTTP method if the `ETag` matches. use crate::headers::{HeaderName, HeaderValue, Headers, IF_MATCH}; use crate::{conditional::ETag, headers::Header}; @@ -8,7 +8,7 @@ use std::iter::Iterator; use std::slice; -/// Apply the HTTP method if the ETag matches. +/// Apply the HTTP method if the `ETag` matches. /// /// # Specifications /// @@ -43,6 +43,7 @@ pub struct IfMatch { impl IfMatch { /// Create a new instance of `IfMatch`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -53,10 +54,7 @@ impl IfMatch { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(IF_MATCH) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(IF_MATCH) else { return Ok(None) }; let mut wildcard = false; for value in headers { @@ -79,16 +77,18 @@ impl IfMatch { } /// Returns `true` if a wildcard directive was set. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -111,8 +111,8 @@ impl Header for IfMatch { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { - 0 => write!(output, "{}", etag).unwrap(), - _ => write!(output, ", {}", etag).unwrap(), + 0 => write!(output, "{etag}").unwrap(), + _ => write!(output, ", {etag}").unwrap(), }; } diff --git a/src/conditional/if_modified_since.rs b/src/conditional/if_modified_since.rs index e5566a12..887b7e2d 100644 --- a/src/conditional/if_modified_since.rs +++ b/src/conditional/if_modified_since.rs @@ -42,21 +42,20 @@ pub struct IfModifiedSince { impl IfModifiedSince { /// Create a new instance of `IfModifiedSince`. + #[must_use] pub fn new(instant: SystemTime) -> Self { Self { instant } } /// Returns the last modification time listed. + #[must_use] pub fn modified(&self) -> SystemTime { self.instant } /// Create an instance of `IfModifiedSince` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(IF_MODIFIED_SINCE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(IF_MODIFIED_SINCE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/conditional/if_none_match.rs b/src/conditional/if_none_match.rs index b4b37af9..e664b3e0 100644 --- a/src/conditional/if_none_match.rs +++ b/src/conditional/if_none_match.rs @@ -1,4 +1,4 @@ -//! Apply the HTTP method if the ETags do not match. +//! Apply the HTTP method if the `ETags` do not match. //! //! This is used to update caches or to prevent uploading a new resource when //! one already exists. @@ -11,7 +11,7 @@ use std::iter::Iterator; use std::slice; -/// Apply the HTTP method if the ETags do not match. +/// Apply the HTTP method if the `ETags` do not match. /// /// This is used to update caches or to prevent uploading a new resource when /// one already exists. @@ -49,6 +49,7 @@ pub struct IfNoneMatch { impl IfNoneMatch { /// Create a new instance of `IfNoneMatch`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -59,10 +60,7 @@ impl IfNoneMatch { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(IF_NONE_MATCH) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(IF_NONE_MATCH) else { return Ok(None) }; let mut wildcard = false; for value in headers { @@ -85,16 +83,18 @@ impl IfNoneMatch { } /// Returns `true` if a wildcard directive was set. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -117,8 +117,8 @@ impl Header for IfNoneMatch { let mut output = String::new(); for (n, etag) in self.entries.iter().enumerate() { match n { - 0 => write!(output, "{}", etag).unwrap(), - _ => write!(output, ", {}", etag).unwrap(), + 0 => write!(output, "{etag}").unwrap(), + _ => write!(output, ", {etag}").unwrap(), }; } diff --git a/src/conditional/if_unmodified_since.rs b/src/conditional/if_unmodified_since.rs index 2d964271..08e188dc 100644 --- a/src/conditional/if_unmodified_since.rs +++ b/src/conditional/if_unmodified_since.rs @@ -42,21 +42,20 @@ pub struct IfUnmodifiedSince { impl IfUnmodifiedSince { /// Create a new instance of `IfUnmodifiedSince`. + #[must_use] pub fn new(instant: SystemTime) -> Self { Self { instant } } /// Returns the last modification time listed. + #[must_use] pub fn modified(&self) -> SystemTime { self.instant } /// Create an instance of `IfUnmodifiedSince` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(IF_UNMODIFIED_SINCE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(IF_UNMODIFIED_SINCE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/conditional/last_modified.rs b/src/conditional/last_modified.rs index dc71fc1b..143827f3 100644 --- a/src/conditional/last_modified.rs +++ b/src/conditional/last_modified.rs @@ -41,21 +41,20 @@ pub struct LastModified { impl LastModified { /// Create a new instance of `LastModified`. + #[must_use] pub fn new(instant: SystemTime) -> Self { Self { instant } } /// Returns the last modification time listed. + #[must_use] pub fn modified(&self) -> SystemTime { self.instant } /// Create an instance of `LastModified` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(LAST_MODIFIED) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(LAST_MODIFIED) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/conditional/vary.rs b/src/conditional/vary.rs index 9023811a..d2fa4fcb 100644 --- a/src/conditional/vary.rs +++ b/src/conditional/vary.rs @@ -1,4 +1,4 @@ -//! Apply the HTTP method if the ETag matches. +//! Apply the HTTP method if the `ETag` matches. use crate::headers::{Header, HeaderName, HeaderValue, Headers, VARY}; @@ -8,7 +8,7 @@ use std::iter::Iterator; use std::slice; use std::str::FromStr; -/// Apply the HTTP method if the ETag matches. +/// Apply the HTTP method if the `ETag` matches. /// /// # Specifications /// @@ -43,6 +43,7 @@ pub struct Vary { impl Vary { /// Create a new instance of `Vary`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -53,10 +54,7 @@ impl Vary { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(VARY) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(VARY) else { return Ok(None) }; let mut wildcard = false; for value in headers { @@ -75,13 +73,14 @@ impl Vary { } /// Returns `true` if a wildcard directive was set. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// Push a directive into the list of entries. @@ -91,6 +90,7 @@ impl Vary { } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -118,8 +118,8 @@ impl Header for Vary { .parse() .expect("Could not convert a HeaderName into a HeaderValue"); match n { - 0 => write!(output, "{}", directive).unwrap(), - _ => write!(output, ", {}", directive).unwrap(), + 0 => write!(output, "{directive}").unwrap(), + _ => write!(output, ", {directive}").unwrap(), }; } diff --git a/src/content/accept.rs b/src/content/accept.rs index 87dad909..6de0577b 100644 --- a/src/content/accept.rs +++ b/src/content/accept.rs @@ -55,6 +55,7 @@ pub struct Accept { impl Accept { /// Create a new instance of `Accept`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -65,10 +66,7 @@ impl Accept { /// Create an instance of `Accept` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(ACCEPT) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(ACCEPT) else { return Ok(None) }; let mut wildcard = false; @@ -76,16 +74,18 @@ impl Accept { for part in value.as_str().trim().split(',') { let part = part.trim(); - // Handle empty strings, and wildcard directives. + // Handle empty strings. if part.is_empty() { continue; - } else if part == "*" { + } + // Handle wildcard directives. + if part == "*" { wildcard = true; continue; } // Try and parse a directive from a str. If the directive is - // unkown we skip it. + // unknown we skip it. let entry = MediaTypeProposal::from_str(part)?; entries.push(entry); } @@ -100,13 +100,14 @@ impl Accept { } /// Returns `true` if a wildcard directive was passed. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// Sort the header directives by weight. @@ -147,6 +148,7 @@ impl Accept { } /// An iterator visiting all entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -170,8 +172,8 @@ impl Header for Accept { for (n, directive) in self.entries.iter().enumerate() { let directive: HeaderValue = directive.clone().into(); match n { - 0 => write!(output, "{}", directive).unwrap(), - _ => write!(output, ", {}", directive).unwrap(), + 0 => write!(output, "{directive}").unwrap(), + _ => write!(output, ", {directive}").unwrap(), }; } diff --git a/src/content/accept_encoding.rs b/src/content/accept_encoding.rs index 5c469a40..01385510 100644 --- a/src/content/accept_encoding.rs +++ b/src/content/accept_encoding.rs @@ -46,6 +46,7 @@ pub struct AcceptEncoding { impl AcceptEncoding { /// Create a new instance of `AcceptEncoding`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -56,10 +57,7 @@ impl AcceptEncoding { /// Create an instance of `AcceptEncoding` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(ACCEPT_ENCODING) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(ACCEPT_ENCODING) else { return Ok(None) }; let mut wildcard = false; @@ -67,16 +65,18 @@ impl AcceptEncoding { for part in value.as_str().trim().split(',') { let part = part.trim(); - // Handle empty strings, and wildcard directives. + // Handle empty strings. if part.is_empty() { continue; - } else if part == "*" { + } + // Handle wildcard directives. + if part == "*" { wildcard = true; continue; } // Try and parse a directive from a str. If the directive is - // unkown we skip it. + // unknown we skip it. if let Some(entry) = EncodingProposal::from_str(part)? { entries.push(entry); } @@ -92,13 +92,14 @@ impl AcceptEncoding { } /// Returns `true` if a wildcard directive was passed. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// Sort the header directives by weight. @@ -139,6 +140,7 @@ impl AcceptEncoding { } /// An iterator visiting all entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -163,8 +165,8 @@ impl Header for AcceptEncoding { for (n, directive) in self.entries.iter().enumerate() { let directive: HeaderValue = (*directive).into(); match n { - 0 => write!(output, "{}", directive).unwrap(), - _ => write!(output, ", {}", directive).unwrap(), + 0 => write!(output, "{directive}").unwrap(), + _ => write!(output, ", {directive}").unwrap(), }; } diff --git a/src/content/content_encoding.rs b/src/content/content_encoding.rs index bbab123c..eb8dcc63 100644 --- a/src/content/content_encoding.rs +++ b/src/content/content_encoding.rs @@ -38,16 +38,14 @@ pub struct ContentEncoding { impl ContentEncoding { /// Create a new instance of `CacheControl`. + #[must_use] pub fn new(encoding: Encoding) -> Self { Self { inner: encoding } } /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(CONTENT_ENCODING) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(CONTENT_ENCODING) else { return Ok(None) }; let mut inner = None; @@ -62,6 +60,7 @@ impl ContentEncoding { } /// Access the encoding kind. + #[must_use] pub fn encoding(&self) -> Encoding { self.inner } diff --git a/src/content/content_length.rs b/src/content/content_length.rs index 4bae42f2..9d47f6ff 100644 --- a/src/content/content_length.rs +++ b/src/content/content_length.rs @@ -33,16 +33,14 @@ pub struct ContentLength { #[allow(clippy::len_without_is_empty)] impl ContentLength { /// Create a new instance. + #[must_use] pub fn new(length: u64) -> Self { Self { length } } /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(CONTENT_LENGTH) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(CONTENT_LENGTH) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -52,6 +50,7 @@ impl ContentLength { } /// Get the content length. + #[must_use] pub fn len(&self) -> u64 { self.length } diff --git a/src/content/content_location.rs b/src/content/content_location.rs index 61c09135..286caab2 100644 --- a/src/content/content_location.rs +++ b/src/content/content_location.rs @@ -37,6 +37,7 @@ pub struct ContentLocation { impl ContentLocation { /// Create a new instance of `Content-Location` header. + #[must_use] pub fn new(url: Url) -> Self { Self { url } } @@ -47,24 +48,19 @@ impl ContentLocation { U: TryInto, U::Error: std::fmt::Debug, { - let headers = match headers.as_ref().get(CONTENT_LOCATION) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(CONTENT_LOCATION) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. let value = headers.iter().last().unwrap(); - let base = match base_url.try_into() { - Ok(b) => b, - Err(_) => bail!(400, "Invalid base url provided"), - }; + let Ok(base) = base_url.try_into() else {bail!(400, "Invalid base url provided")}; let url = base.join(value.as_str().trim()).status(400)?; Ok(Some(Self { url })) } /// Get the url. + #[must_use] pub fn location(&self) -> &Url { &self.url } @@ -77,7 +73,7 @@ impl ContentLocation { { self.url = location .try_into() - .expect("Could not convert into valid URL") + .expect("Could not convert into valid URL"); } } diff --git a/src/content/content_type.rs b/src/content/content_type.rs index 9397165c..4b474006 100644 --- a/src/content/content_type.rs +++ b/src/content/content_type.rs @@ -58,10 +58,7 @@ impl ContentType { /// reference the current environment. In HTTP/1.1 and above this value can /// always be determined from the request. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(CONTENT_TYPE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(CONTENT_TYPE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/content/encoding_proposal.rs b/src/content/encoding_proposal.rs index 7d329447..12f5b9e6 100644 --- a/src/content/encoding_proposal.rs +++ b/src/content/encoding_proposal.rs @@ -25,7 +25,7 @@ impl EncodingProposal { ensure!( weight.is_sign_positive() && weight <= 1.0, "EncodingProposal should have a weight between 0.0 and 1.0" - ) + ); } Ok(Self { @@ -35,21 +35,20 @@ impl EncodingProposal { } /// Get the proposed encoding. + #[must_use] pub fn encoding(&self) -> &Encoding { &self.encoding } /// Get the weight of the proposal. + #[must_use] pub fn weight(&self) -> Option { self.weight } pub(crate) fn from_str(s: &str) -> crate::Result> { let mut parts = s.split(';'); - let encoding = match Encoding::from_str(parts.next().unwrap()) { - Some(encoding) => encoding, - None => return Ok(None), - }; + let Some(encoding) = Encoding::from_str(parts.next().unwrap()) else { return Ok(None) }; let weight = parts.next().map(parse_weight).transpose()?; Ok(Some(Self::new(encoding, weight)?)) @@ -98,7 +97,7 @@ impl DerefMut for EncodingProposal { // NOTE: This comparison does not include a notion of `*` (any value is valid). // that needs to be handled separately. impl PartialOrd for EncodingProposal { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { match (self.weight, other.weight) { (Some(left), Some(right)) => left.partial_cmp(&right), (Some(_), None) => Some(Ordering::Greater), diff --git a/src/content/media_type_proposal.rs b/src/content/media_type_proposal.rs index 622558de..6f824c8c 100644 --- a/src/content/media_type_proposal.rs +++ b/src/content/media_type_proposal.rs @@ -27,7 +27,7 @@ impl MediaTypeProposal { ensure!( weight.is_sign_positive() && weight <= 1.0, "MediaTypeProposal should have a weight between 0.0 and 1.0" - ) + ); } if weight.is_none() { return Ok(Self { @@ -42,12 +42,14 @@ impl MediaTypeProposal { }) } - /// Get the proposed media_type. + /// Get the proposed `media_type`. + #[must_use] pub fn media_type(&self) -> &Mime { &self.media_type } /// Get the weight of the proposal. + #[must_use] pub fn weight(&self) -> Option { self.weight } @@ -115,7 +117,7 @@ impl DerefMut for MediaTypeProposal { // NOTE: This comparison does not include a notion of `*` (any value is valid). // that needs to be handled separately. impl PartialOrd for MediaTypeProposal { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { match (self.weight, other.weight) { (Some(left), Some(right)) => left.partial_cmp(&right), (Some(_), None) => Some(Ordering::Greater), diff --git a/src/error.rs b/src/error.rs index 04fbcd8d..d686814e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,7 +15,7 @@ pub type Result = std::result::Result; /// The error type for HTTP operations. pub struct Error { error: anyhow::Error, - status: crate::StatusCode, + status: StatusCode, type_name: Option<&'static str>, } @@ -75,6 +75,7 @@ impl Error { } /// Get the status code associated with this error. + #[must_use] pub fn status(&self) -> StatusCode { self.status } @@ -119,12 +120,14 @@ impl Error { #[cfg(not(backtrace))] #[allow(missing_docs)] + #[must_use] pub const fn backtrace(&self) -> Option { None } /// Returns the inner [`anyhow::Error`] /// Note: This will lose status code information + #[must_use] pub fn into_inner(self) -> anyhow::Error { self.error } @@ -142,6 +145,7 @@ impl Error { } /// Downcast this error object by reference. + #[must_use] pub fn downcast_ref(&self) -> Option<&E> where E: Display + Debug + Send + Sync + 'static, @@ -158,6 +162,7 @@ impl Error { } /// Retrieves a reference to the type name of the error, if available. + #[must_use] pub fn type_name(&self) -> Option<&str> { self.type_name } @@ -165,7 +170,7 @@ impl Error { /// Converts anything which implements `Display` into an `http_types::Error`. /// /// This is handy for errors which are not `Send + Sync + 'static` because `std::error::Error` requires `Display`. - /// Note that any assiciated context not included in the `Display` output will be lost, + /// Note that any associated context not included in the `Display` output will be lost, /// and so this may be lossy for some types which implement `std::error::Error`. /// /// **Note: Prefer `error.into()` via `From>` when possible!** @@ -176,12 +181,12 @@ impl Error { /// Converts anything which implements `Debug` into an `http_types::Error`. /// /// This is handy for errors which are not `Send + Sync + 'static` because `std::error::Error` requires `Debug`. - /// Note that any assiciated context not included in the `Debug` output will be lost, + /// Note that any associated context not included in the `Debug` output will be lost, /// and so this may be lossy for some types which implement `std::error::Error`. /// /// **Note: Prefer `error.into()` via `From>` when possible!** pub fn from_debug(error: D) -> Self { - anyhow::Error::msg(format!("{:?}", error)).into() + anyhow::Error::msg(format!("{error:?}")).into() } } diff --git a/src/extensions.rs b/src/extensions.rs index bd89718f..aefae62f 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -36,6 +36,7 @@ impl Extensions { } /// Check if container contains value for type + #[must_use] pub fn contains(&self) -> bool { self.map .as_ref() @@ -44,6 +45,7 @@ impl Extensions { } /// Get a reference to a value previously inserted on this `Extensions`. + #[must_use] pub fn get(&self) -> Option<&T> { self.map .as_ref() @@ -82,11 +84,16 @@ impl fmt::Debug for Extensions { } } -// With TypeIds as keys, there's no need to hash them. So we simply use an identy hasher. +// With TypeIds as keys, there's no need to hash them. So we simply use an identity hasher. #[derive(Default)] struct IdHasher(u64); impl Hasher for IdHasher { + #[inline] + fn finish(&self) -> u64 { + self.0 + } + fn write(&mut self, _: &[u8]) { unreachable!("TypeId calls write_u64"); } @@ -95,11 +102,6 @@ impl Hasher for IdHasher { fn write_u64(&mut self, id: u64) { self.0 = id; } - - #[inline] - fn finish(&self) -> u64 { - self.0 - } } #[cfg(test)] diff --git a/src/headers/header_name.rs b/src/headers/header_name.rs index f0953a39..fa7a6f0c 100644 --- a/src/headers/header_name.rs +++ b/src/headers/header_name.rs @@ -21,7 +21,7 @@ impl HeaderName { bytes.make_ascii_lowercase(); // This is permitted because ASCII is valid UTF-8, and we just checked that. - let string = unsafe { String::from_utf8_unchecked(bytes.to_vec()) }; + let string = unsafe { String::from_utf8_unchecked(bytes.clone()) }; Ok(HeaderName(Cow::Owned(string))) } @@ -35,6 +35,7 @@ impl HeaderName { } /// Returns the header name as a `&str`. + #[must_use] pub fn as_str(&self) -> &'_ str { &self.0 } @@ -46,8 +47,9 @@ impl HeaderName { /// /// This function is unsafe because it does not check that the bytes passed to it are valid /// ASCII. If this constraint is violated, it may cause memory - /// unsafety issues with future users of the HeaderName, as the rest of the library assumes + /// unsafety issues with future users of the `HeaderName`, as the rest of the library assumes /// that Strings are valid ASCII. + #[must_use] pub unsafe fn from_bytes_unchecked(mut bytes: Vec) -> Self { bytes.make_ascii_lowercase(); let string = String::from_utf8_unchecked(bytes); @@ -179,6 +181,6 @@ mod tests { #[test] fn test_debug() { let header_name = HeaderName::from_str("hello").unwrap(); - assert_eq!(format!("{:?}", header_name), "\"hello\""); + assert_eq!(format!("{header_name:?}"), "\"hello\""); } } diff --git a/src/headers/header_value.rs b/src/headers/header_value.rs index 6620a98b..0fc7ff37 100644 --- a/src/headers/header_value.rs +++ b/src/headers/header_value.rs @@ -35,14 +35,16 @@ impl HeaderValue { /// /// This function is unsafe because it does not check that the bytes passed to it are valid /// ASCII. If this constraint is violated, it may cause memory - /// unsafety issues with future users of the HeaderValue, as the rest of the library assumes + /// unsafety issues with future users of the `HeaderValue`, as the rest of the library assumes /// that Strings are valid ASCII. + #[must_use] pub unsafe fn from_bytes_unchecked(bytes: Vec) -> Self { let string = String::from_utf8_unchecked(bytes); Self { inner: string } } /// Get the header value as a `&str` + #[must_use] pub fn as_str(&self) -> &str { &self.inner } @@ -51,7 +53,7 @@ impl HeaderValue { impl From for HeaderValue { fn from(mime: Mime) -> Self { HeaderValue { - inner: format!("{}", mime), + inner: format!("{mime}"), } } } @@ -68,7 +70,7 @@ impl From> for HeaderValue { impl From<&Mime> for HeaderValue { fn from(mime: &Mime) -> Self { HeaderValue { - inner: format!("{}", mime), + inner: format!("{mime}"), } } } @@ -148,6 +150,6 @@ mod tests { #[test] fn test_debug() { let header_value = HeaderValue::from_str("foo0").unwrap(); - assert_eq!(format!("{:?}", header_value), "\"foo0\""); + assert_eq!(format!("{header_value:?}"), "\"foo0\""); } } diff --git a/src/headers/header_values.rs b/src/headers/header_values.rs index 1e9de875..47970a4d 100644 --- a/src/headers/header_values.rs +++ b/src/headers/header_values.rs @@ -16,10 +16,11 @@ pub struct HeaderValues { impl HeaderValues { /// Move all values from `other` into `self`, leaving `other` empty. pub fn append(&mut self, other: &mut Self) { - self.inner.append(&mut other.inner) + self.inner.append(&mut other.inner); } /// Returns a reference or a value depending on the type of index. + #[must_use] pub fn get(&self, index: usize) -> Option<&HeaderValue> { self.inner.get(index) } @@ -31,11 +32,13 @@ impl HeaderValues { /// Returns `true` if there is a value corresponding to the specified `HeaderValue` in the list, /// `false` otherwise. + #[must_use] pub fn contains(&self, value: &HeaderValue) -> bool { self.inner.contains(value) } /// Returns the last `HeaderValue`. + #[must_use] pub fn last(&self) -> &HeaderValue { self.inner .last() @@ -43,6 +46,7 @@ impl HeaderValues { } /// An iterator visiting all header values in arbitrary order. + #[must_use] pub fn iter(&self) -> Values<'_> { Values::new_values(self) } @@ -196,13 +200,13 @@ mod tests { let header_values = HeaderValues { inner: vec!["foo0".parse().unwrap()], }; - assert_eq!(format!("{:?}", header_values), "\"foo0\""); + assert_eq!(format!("{header_values:?}"), "\"foo0\""); } #[test] fn test_debug_multiple() { let header_values = HeaderValues { inner: vec!["foo0".parse().unwrap(), "foo1".parse().unwrap()], }; - assert_eq!(format!("{:?}", header_values), r#"["foo0", "foo1"]"#); + assert_eq!(format!("{header_values:?}"), r#"["foo0", "foo1"]"#); } } diff --git a/src/headers/headers.rs b/src/headers/headers.rs index a7a9d90e..8e44132a 100644 --- a/src/headers/headers.rs +++ b/src/headers/headers.rs @@ -93,6 +93,7 @@ impl Headers { } /// An iterator visiting all header pairs in arbitrary order. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.headers.iter(), @@ -108,6 +109,7 @@ impl Headers { } /// An iterator visiting all header names in arbitrary order. + #[must_use] pub fn names(&self) -> Names<'_> { Names { inner: self.headers.keys(), @@ -115,6 +117,7 @@ impl Headers { } /// An iterator visiting all header values in arbitrary order. + #[must_use] pub fn values(&self) -> Values<'_> { Values::new(self.headers.values()) } @@ -236,7 +239,7 @@ mod tests { fn test_debug_single() { let mut headers = Headers::new(); headers.insert("single", "foo0").unwrap(); - assert_eq!(format!("{:?}", headers), r#"{"single": "foo0"}"#); + assert_eq!(format!("{headers:?}"), r#"{"single": "foo0"}"#); } #[test] @@ -244,6 +247,6 @@ mod tests { let mut headers = Headers::new(); headers.append("multi", "foo0").unwrap(); headers.append("multi", "foo1").unwrap(); - assert_eq!(format!("{:?}", headers), r#"{"multi": ["foo0", "foo1"]}"#); + assert_eq!(format!("{headers:?}"), r#"{"multi": ["foo0", "foo1"]}"#); } } diff --git a/src/headers/values.rs b/src/headers/values.rs index 810c0514..10d4e267 100644 --- a/src/headers/values.rs +++ b/src/headers/values.rs @@ -47,18 +47,13 @@ impl<'a> Iterator for Values<'a> { } // Get the next item - match self.slot.unwrap().get(self.cursor) { + if let Some(item) = self.slot.unwrap().get(self.cursor) { // If an item is found, increment the cursor and return the item. - Some(item) => { - self.cursor += 1; - return Some(item); - } - // If no item is found, unset the slot and loop again. - None => { - self.slot = None; - continue; - } + self.cursor += 1; + return Some(item); } + // If no item is found, unset the slot and loop again. + self.slot = None; } } diff --git a/src/hyperium_http.rs b/src/hyperium_http.rs index 81d33425..e25378dc 100644 --- a/src/hyperium_http.rs +++ b/src/hyperium_http.rs @@ -158,11 +158,11 @@ fn hyperium_headers_to_headers( fn headers_to_hyperium_headers(headers: &mut Headers, hyperium_headers: &mut http::HeaderMap) { for (name, values) in headers { - let name = format!("{}", name).into_bytes(); + let name = format!("{name}").into_bytes(); let name = http::header::HeaderName::from_bytes(&name).unwrap(); for value in values.iter() { - let value = format!("{}", value).into_bytes(); + let value = format!("{value}").into_bytes(); let value = http::header::HeaderValue::from_bytes(&value).unwrap(); hyperium_headers.append(&name, value); } @@ -170,22 +170,22 @@ fn headers_to_hyperium_headers(headers: &mut Headers, hyperium_headers: &mut htt } // Neither type is defined in this lib, so we can't do From/Into impls -fn from_uri_to_url(uri: http::Uri) -> Result { - format!("{}", uri).parse() +fn from_uri_to_url(uri: &http::Uri) -> Result { + format!("{uri}").parse() } // Neither type is defined in this lib, so we can't do From/Into impls fn from_url_to_uri(url: &Url) -> http::Uri { - http::Uri::try_from(&format!("{}", url)).unwrap() + http::Uri::try_from(&format!("{url}")).unwrap() } impl TryFrom> for Request { - type Error = crate::Error; + type Error = Error; fn try_from(req: http::Request) -> Result { let (parts, body) = req.into_parts(); let method = parts.method.into(); - let url = from_uri_to_url(parts.uri)?; + let url = from_uri_to_url(&parts.uri)?; let mut req = Request::new(method, url); req.set_body(body); req.set_version(Some(parts.version.into())); @@ -197,7 +197,10 @@ impl TryFrom> for Request { impl From for http::Request { fn from(mut req: Request) -> Self { let method: http::Method = req.method().into(); - let version = req.version().map(|v| v.into()).unwrap_or_default(); + let version = req + .version() + .map(std::convert::Into::into) + .unwrap_or_default(); let mut builder = http::request::Builder::new() .method(method) .uri(from_url_to_uri(req.url())) @@ -208,7 +211,7 @@ impl From for http::Request { } impl TryFrom> for Response { - type Error = crate::Error; + type Error = Error; fn try_from(res: http::Response) -> Result { let (parts, body) = res.into_parts(); let mut res = Response::new(parts.status); @@ -222,7 +225,10 @@ impl TryFrom> for Response { impl From for http::Response { fn from(mut res: Response) -> Self { let status: u16 = res.status().into(); - let version = res.version().map(|v| v.into()).unwrap_or_default(); + let version = res + .version() + .map(std::convert::Into::into) + .unwrap_or_default(); let mut builder = http::response::Builder::new() .status(status) .version(version); diff --git a/src/method.rs b/src/method.rs index 7ad2b46b..f4577898 100644 --- a/src/method.rs +++ b/src/method.rs @@ -341,6 +341,7 @@ impl Method { /// Whether a method is considered "safe", meaning the request is essentially read-only. /// /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.1) for more details. + #[must_use] pub fn is_safe(&self) -> bool { matches!( self, diff --git a/src/mime/mod.rs b/src/mime/mod.rs index f416de3d..70955593 100644 --- a/src/mime/mod.rs +++ b/src/mime/mod.rs @@ -89,16 +89,19 @@ impl Mime { /// /// According to the spec this method should be named `type`, but that's a reserved keyword in /// Rust so hence prefix with `base` instead. + #[must_use] pub fn basetype(&self) -> &str { &self.basetype } /// Access the Mime's `subtype` value. + #[must_use] pub fn subtype(&self) -> &str { &self.subtype } /// Access the Mime's `essence` value. + #[must_use] pub fn essence(&self) -> &str { &self.essence } @@ -146,6 +149,7 @@ impl Mime { /// // A mime type more general than another mime type is not a subset /// assert!(!Mime::from_str("*/css;encoding=utf-8").unwrap().subset_eq(&Mime::from_str("text/css").unwrap())); /// ``` + #[must_use] pub fn subset_eq(&self, other: &Mime) -> bool { if other.basetype() != "*" && self.basetype() != other.basetype() { return false; @@ -153,12 +157,8 @@ impl Mime { if other.subtype() != "*" && self.subtype() != other.subtype() { return false; } - for (name, value) in other.params.iter() { - if !self - .param(name.clone()) - .map(|v| v == value) - .unwrap_or(false) - { + for (name, value) in &other.params { + if !self.param(name.clone()).map_or(false, |v| v == value) { return false; } } @@ -213,6 +213,7 @@ pub struct ParamName(Cow<'static, str>); impl ParamName { /// Get the name as a `&str` + #[must_use] pub fn as_str(&self) -> &str { &self.0 } @@ -248,6 +249,7 @@ pub struct ParamValue(Cow<'static, str>); impl ParamValue { /// Get the value as a `&str` + #[must_use] pub fn as_str(&self) -> &str { &self.0 } diff --git a/src/mime/parse.rs b/src/mime/parse.rs index f2ec5698..4f9e3d26 100644 --- a/src/mime/parse.rs +++ b/src/mime/parse.rs @@ -64,16 +64,15 @@ pub(crate) fn parse(input: &str) -> crate::Result { if input.is_empty() { // 6. break; - } else { + } + if input.starts_with(';') { // 5. - if input.starts_with(';') { - continue; - } else { - // It's a '=' - input = &input[1..]; - } + continue; } + // It's a '=' + input = &input[1..]; + let parameter_value = if input.starts_with('"') { // 8. // implementation of https://fetch.spec.whatwg.org/#collect-an-http-quoted-string @@ -210,9 +209,9 @@ pub(crate) fn format(mime_type: &Mime, f: &mut fmt::Formatter<'_>) -> fmt::Resul if mime_type.is_utf8 { write!(f, ";charset=utf-8")?; } - for (name, value) in mime_type.params.iter() { + for (name, value) in &mime_type.params { if value.0.chars().all(is_http_token_code_point) && !value.0.is_empty() { - write!(f, ";{}={}", name, value)?; + write!(f, ";{name}={value}")?; } else { let value = value .0 @@ -222,7 +221,7 @@ pub(crate) fn format(mime_type: &Mime, f: &mut fmt::Formatter<'_>) -> fmt::Resul c => EscapeMimeValue::char(c), }) .collect::(); - write!(f, ";{}=\"{}\"", name, value)?; + write!(f, ";{name}=\"{value}\"")?; } } Ok(()) diff --git a/src/other/date.rs b/src/other/date.rs index 1e381ffe..9ed4d094 100644 --- a/src/other/date.rs +++ b/src/other/date.rs @@ -39,11 +39,13 @@ pub struct Date { impl Date { /// Create a new instance. + #[must_use] pub fn new(at: SystemTime) -> Self { Self { at } } /// Create a new instance with the date set to now. + #[must_use] pub fn now() -> Self { Self { at: SystemTime::now(), @@ -52,10 +54,7 @@ impl Date { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(DATE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(DATE) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -80,7 +79,7 @@ impl Header for Date { fn header_value(&self) -> HeaderValue { let date: HttpDate = self.at.into(); - let output = format!("{}", date); + let output = format!("{date}"); // SAFETY: the internal string is validated to be ASCII. unsafe { HeaderValue::from_bytes_unchecked(output.into()) } diff --git a/src/other/expect.rs b/src/other/expect.rs index 086c0d09..1f169b33 100644 --- a/src/other/expect.rs +++ b/src/other/expect.rs @@ -36,16 +36,14 @@ pub struct Expect { impl Expect { /// Create a new instance of `Expect`. + #[must_use] pub fn new() -> Self { Self { _priv: () } } /// Create an instance of `Expect` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(EXPECT) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(EXPECT) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. diff --git a/src/other/referer.rs b/src/other/referer.rs index 5a860ab9..8846a62a 100644 --- a/src/other/referer.rs +++ b/src/other/referer.rs @@ -40,6 +40,7 @@ pub struct Referer { impl Referer { /// Create a new instance of `Referer` header. + #[must_use] pub fn new(location: Url) -> Self { Self { location } } @@ -50,10 +51,7 @@ impl Referer { U: TryInto, U::Error: std::fmt::Debug, { - let headers = match headers.as_ref().get(REFERER) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(REFERER) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -71,6 +69,7 @@ impl Referer { } /// Get the url. + #[must_use] pub fn location(&self) -> &Url { &self.location } diff --git a/src/other/retry_after.rs b/src/other/retry_after.rs index 21404598..efb57a0e 100644 --- a/src/other/retry_after.rs +++ b/src/other/retry_after.rs @@ -42,6 +42,7 @@ impl RetryAfter { /// Create a new instance from a `Duration`. /// /// This value will be encoded over the wire as a relative offset in seconds. + #[must_use] pub fn new(dur: Duration) -> Self { Self { inner: RetryDirective::Duration(dur), @@ -51,6 +52,7 @@ impl RetryAfter { /// Create a new instance from a `SystemTime` instant. /// /// This value will be encoded a specific `Date` over the wire. + #[must_use] pub fn new_at(at: SystemTime) -> Self { Self { inner: RetryDirective::SystemTime(at), @@ -64,12 +66,11 @@ impl RetryAfter { None => return Ok(None), }; - let inner = match header.as_str().parse::() { - Ok(dur) => RetryDirective::Duration(Duration::from_secs(dur)), - Err(_) => { - let at = parse_http_date(header.as_str())?; - RetryDirective::SystemTime(at) - } + let inner = if let Ok(dur) = header.as_str().parse::() { + RetryDirective::Duration(Duration::from_secs(dur)) + } else { + let at = parse_http_date(header.as_str())?; + RetryDirective::SystemTime(at) }; Ok(Some(Self { inner })) } @@ -115,7 +116,7 @@ impl From for SystemTime { /// What value are we decoding into? /// -/// This value is intionally never exposes; all end-users want is a `Duration` +/// This value is intentionally never exposed; all end-users want is a `Duration` /// value that tells them how long to wait for before trying again. #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)] enum RetryDirective { diff --git a/src/other/source_map.rs b/src/other/source_map.rs index 5412c6e1..e0e657da 100644 --- a/src/other/source_map.rs +++ b/src/other/source_map.rs @@ -37,6 +37,7 @@ pub struct SourceMap { impl SourceMap { /// Create a new instance of `SourceMap` header. + #[must_use] pub fn new(location: Url) -> Self { Self { location } } @@ -47,10 +48,7 @@ impl SourceMap { U: TryInto, U::Error: std::fmt::Debug, { - let headers = match headers.as_ref().get(SOURCE_MAP) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(SOURCE_MAP) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -68,6 +66,7 @@ impl SourceMap { } /// Get the url. + #[must_use] pub fn location(&self) -> &Url { &self.location } diff --git a/src/parse_utils.rs b/src/parse_utils.rs index a2dc2356..4b511fd4 100644 --- a/src/parse_utils.rs +++ b/src/parse_utils.rs @@ -140,8 +140,8 @@ mod test { let s = c.to_string(); assert_eq!(parse_token(&s), (None, &*s)); - let s = format!("match{}rest", s); - assert_eq!(parse_token(&s), (Some("match"), &*format!("{}rest", c))); + let s = format!("match{s}rest"); + assert_eq!(parse_token(&s), (Some("match"), &*format!("{c}rest"))); } } diff --git a/src/proxies/forwarded.rs b/src/proxies/forwarded.rs index 30e491b0..8b79a292 100644 --- a/src/proxies/forwarded.rs +++ b/src/proxies/forwarded.rs @@ -154,7 +154,7 @@ impl<'a> Forwarded<'a> { .map(|v| { let v = v.trim(); match v.parse::().ok() { - Some(IpAddr::V6(v6)) => Cow::Owned(format!(r#"[{}]"#, v6)), + Some(IpAddr::V6(v6)) => Cow::Owned(format!(r#"[{v6}]"#)), _ => Cow::Borrowed(v), } }) @@ -176,10 +176,10 @@ impl<'a> Forwarded<'a> { if !forwarded_for.is_empty() || by.is_some() || proto.is_some() || host.is_some() { Ok(Some(Self { - forwarded_for, by, - proto, + forwarded_for, host, + proto, })) } else { Ok(None) @@ -299,6 +299,7 @@ impl<'a> Forwarded<'a> { /// Transform a borrowed Forwarded into an owned /// Forwarded. This is a noop if the Forwarded is already owned. + #[must_use] pub fn into_owned(self) -> Forwarded<'static> { Forwarded { by: self.by.map(|by| Cow::Owned(by.into_owned())), @@ -313,6 +314,7 @@ impl<'a> Forwarded<'a> { } /// Builds a new empty Forwarded + #[must_use] pub fn new() -> Self { Self::default() } @@ -323,8 +325,12 @@ impl<'a> Forwarded<'a> { } /// Returns the `for` field of this header + #[must_use] pub fn forwarded_for(&self) -> Vec<&str> { - self.forwarded_for.iter().map(|x| x.as_ref()).collect() + self.forwarded_for + .iter() + .map(std::convert::AsRef::as_ref) + .collect() } /// Sets the `host` field of this header @@ -333,16 +339,18 @@ impl<'a> Forwarded<'a> { } /// Returns the `host` field of this header + #[must_use] pub fn host(&self) -> Option<&str> { self.host.as_deref() } /// Sets the `proto` field of this header pub fn set_proto(&mut self, proto: impl Into>) { - self.proto = Some(proto.into()) + self.proto = Some(proto.into()); } /// Returns the `proto` field of this header + #[must_use] pub fn proto(&self) -> Option<&str> { self.proto.as_deref() } @@ -353,6 +361,7 @@ impl<'a> Forwarded<'a> { } /// Returns the `by` field of this header + #[must_use] pub fn by(&self) -> Option<&str> { self.by.as_deref() } @@ -365,7 +374,7 @@ impl<'a> Header for Forwarded<'a> { fn header_value(&self) -> HeaderValue { let mut output = String::new(); if let Some(by) = self.by() { - write!(&mut output, "by={};", by).unwrap(); + write!(&mut output, "by={by};").unwrap(); } output.push_str( @@ -380,11 +389,11 @@ impl<'a> Header for Forwarded<'a> { output.push(';'); if let Some(host) = self.host() { - write!(&mut output, "host={};", host).unwrap(); + write!(&mut output, "host={host};").unwrap(); } if let Some(proto) = self.proto() { - write!(&mut output, "proto={};", proto).unwrap(); + write!(&mut output, "proto={proto};").unwrap(); } // remove a trailing semicolon @@ -403,19 +412,18 @@ fn parse_value(input: &str) -> (Option>, &str) { } fn format_value(input: &str) -> Cow<'_, str> { - match parse_token(input) { - (_, "") => input.into(), - _ => { - let mut string = String::from("\""); - for ch in input.chars() { - if let '\\' | '"' = ch { - string.push('\\'); - } - string.push(ch); + if let (_, "") = parse_token(input) { + input.into() + } else { + let mut string = String::from("\""); + for ch in input.chars() { + if let '\\' | '"' = ch { + string.push('\\'); } - string.push('"'); - string.into() + string.push(ch); } + string.push('"'); + string.into() } } diff --git a/src/request.rs b/src/request.rs index 6b3bb355..57792d61 100644 --- a/src/request.rs +++ b/src/request.rs @@ -71,25 +71,27 @@ impl Request { /// Sets a string representation of the peer address of this /// request. This might take the form of an ip/fqdn and port or a /// local socket address. - pub fn set_peer_addr(&mut self, peer_addr: Option) { + pub fn set_peer_addr(&mut self, peer_addr: Option) { self.peer_addr = peer_addr.map(|addr| addr.to_string()); } /// Sets a string representation of the local address that this /// request was received on. This might take the form of an ip/fqdn and /// port, or a local socket address. - pub fn set_local_addr(&mut self, local_addr: Option) { + pub fn set_local_addr(&mut self, local_addr: Option) { self.local_addr = local_addr.map(|addr| addr.to_string()); } /// Get the peer socket address for the underlying transport, if /// that information is available for this request. + #[must_use] pub fn peer_addr(&self) -> Option<&str> { self.peer_addr.as_deref() } /// Get the local socket address for the underlying transport, if /// that information is available for this request. + #[must_use] pub fn local_addr(&self) -> Option<&str> { self.local_addr.as_deref() } @@ -100,6 +102,7 @@ impl Request { /// 1. `Forwarded` header `for` key /// 2. The first `X-Forwarded-For` header /// 3. Peer address of the transport + #[must_use] pub fn remote(&self) -> Option<&str> { self.forwarded_for().or_else(|| self.peer_addr()) } @@ -111,6 +114,7 @@ impl Request { /// 2. The first `X-Forwarded-Host` header /// 3. `Host` header /// 4. URL domain, if any + #[must_use] pub fn host(&self) -> Option<&str> { self.forwarded_header_part("host") .or_else(|| { @@ -142,6 +146,7 @@ impl Request { } /// Get the HTTP method + #[must_use] pub fn method(&self) -> Method { self.method } @@ -164,6 +169,7 @@ impl Request { /// # /// # Ok(()) } /// ``` + #[must_use] pub fn url(&self) -> &Url { &self.url } @@ -285,7 +291,7 @@ impl Request { /// /// This consumes the request. If you want to read the body without /// consuming the request, consider using the `take_body` method and - /// then calling `Body::into_string` or using the Request's AsyncRead + /// then calling `Body::into_string` or using the Request's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -313,7 +319,7 @@ impl Request { /// /// This consumes the `Request`. If you want to read the body without /// consuming the request, consider using the `take_body` method and - /// then calling `Body::into_bytes` or using the Request's AsyncRead + /// then calling `Body::into_bytes` or using the Request's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -339,7 +345,7 @@ impl Request { /// /// This consumes the request. If you want to read the body without /// consuming the request, consider using the `take_body` method and - /// then calling `Body::into_json` or using the Request's AsyncRead + /// then calling `Body::into_json` or using the Request's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -375,7 +381,7 @@ impl Request { /// /// This consumes the request. If you want to read the body without /// consuming the request, consider using the `take_body` method and - /// then calling `Body::into_json` or using the Request's AsyncRead + /// then calling `Body::into_json` or using the Request's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -489,6 +495,7 @@ impl Request { } /// Get the current content type + #[must_use] pub fn content_type(&self) -> Option { self.header(CONTENT_TYPE)?.last().as_str().parse().ok() } @@ -499,12 +506,14 @@ impl Request { /// E.g. a string, or a buffer. Consumers of this API should check this /// value to decide whether to use `Chunked` encoding, or set the /// response length. + #[must_use] pub fn len(&self) -> Option { self.body.len() } /// Returns `true` if the request has a set body stream length of zero, /// `false` otherwise. + #[must_use] pub fn is_empty(&self) -> Option { self.body.is_empty() } @@ -526,6 +535,7 @@ impl Request { /// # /// # Ok(()) } /// ``` + #[must_use] pub fn version(&self) -> Option { self.version } @@ -568,11 +578,13 @@ impl Request { } /// Returns `true` if sending trailers is in progress. + #[must_use] pub fn has_trailers(&self) -> bool { self.has_trailers } /// An iterator visiting all header pairs in arbitrary order. + #[must_use] pub fn iter(&self) -> headers::Iter<'_> { self.headers.iter() } @@ -584,16 +596,19 @@ impl Request { } /// An iterator visiting all header names in arbitrary order. + #[must_use] pub fn header_names(&self) -> Names<'_> { self.headers.names() } /// An iterator visiting all header values in arbitrary order. + #[must_use] pub fn header_values(&self) -> Values<'_> { self.headers.values() } /// Returns a reference to the existing local state. + #[must_use] pub fn ext(&self) -> &Extensions { &self.ext } @@ -656,13 +671,13 @@ impl Request { #[cfg(feature = "serde")] pub fn query<'de, T: serde_crate::de::Deserialize<'de>>(&'de self) -> crate::Result { // Default to an empty query string if no query parameter has been specified. - // This allows successful deserialisation of structs where all fields are optional - // when none of those fields has actually been passed by the caller. + // This allows successful deserialization of structs where all fields are optional + // when the caller has actually passed none of those fields. let query = self.url().query().unwrap_or(""); serde_qs::from_str(query).map_err(|e| { // Return the displayable version of the deserialisation error to the caller // for easier debugging. - crate::Error::from_str(crate::StatusCode::BadRequest, format!("{}", e)) + crate::Error::from_str(crate::StatusCode::BadRequest, format!("{e}")) }) } @@ -690,7 +705,7 @@ impl Request { #[cfg(feature = "serde")] pub fn set_query(&mut self, query: &impl Serialize) -> crate::Result<()> { let query = serde_qs::to_string(query) - .map_err(|e| crate::Error::from_str(crate::StatusCode::BadRequest, format!("{}", e)))?; + .map_err(|e| crate::Error::from_str(crate::StatusCode::BadRequest, format!("{e}")))?; self.url.set_query(Some(&query)); Ok(()) } @@ -923,7 +938,7 @@ impl AsyncBufRead for Request { } fn consume(mut self: Pin<&mut Self>, amt: usize) { - Pin::new(&mut self.body).consume(amt) + Pin::new(&mut self.body).consume(amt); } } @@ -1197,7 +1212,7 @@ mod tests { request .insert_header( "x-forwarded-for", - format!("{},proxy.com,other-proxy.com", client), + format!("{client},proxy.com,other-proxy.com"), ) .unwrap(); } @@ -1206,7 +1221,7 @@ mod tests { request .insert_header( "x-forwarded-host", - format!("{},proxy.com,other-proxy.com", host), + format!("{host},proxy.com,other-proxy.com"), ) .unwrap(); } @@ -1215,7 +1230,7 @@ mod tests { request .insert_header( "Forwarded", - format!("by=something.com;for={};host=host.com;proto=http", client), + format!("by=something.com;for={client};host=host.com;proto=http"), ) .unwrap(); } diff --git a/src/response.rs b/src/response.rs index 4b4a4aa6..4d0470af 100644 --- a/src/response.rs +++ b/src/response.rs @@ -82,6 +82,7 @@ impl Response { } /// Get the status + #[must_use] pub fn status(&self) -> StatusCode { self.status } @@ -254,7 +255,7 @@ impl Response { /// /// This consumes the response. If you want to read the body without /// consuming the response, consider using the `take_body` method and - /// then calling `Body::into_string` or using the Response's AsyncRead + /// then calling `Body::into_string` or using the Response's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -281,7 +282,7 @@ impl Response { /// /// This consumes the `Response`. If you want to read the body without /// consuming the response, consider using the `take_body` method and - /// then calling `Body::into_bytes` or using the Response's AsyncRead + /// then calling `Body::into_bytes` or using the Response's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -307,7 +308,7 @@ impl Response { /// /// This consumes the response. If you want to read the body without /// consuming the response, consider using the `take_body` method and - /// then calling `Body::into_json` or using the Response's AsyncRead + /// then calling `Body::into_json` or using the Response's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -344,7 +345,7 @@ impl Response { /// /// This consumes the request. If you want to read the body without /// consuming the request, consider using the `take_body` method and - /// then calling `Body::into_json` or using the Response's AsyncRead + /// then calling `Body::into_json` or using the Response's `AsyncRead` /// implementation to read the body. /// /// # Examples @@ -394,6 +395,7 @@ impl Response { } /// Get the current content type + #[must_use] pub fn content_type(&self) -> Option { self.header(CONTENT_TYPE)?.last().as_str().parse().ok() } @@ -404,12 +406,14 @@ impl Response { /// E.g. a string, or a buffer. Consumers of this API should check this /// value to decide whether to use `Chunked` encoding, or set the /// response length. + #[must_use] pub fn len(&self) -> Option { self.body.len() } /// Returns `true` if the set length of the body stream is zero, `false` /// otherwise. + #[must_use] pub fn is_empty(&self) -> Option { self.body.is_empty() } @@ -431,6 +435,7 @@ impl Response { /// # /// # Ok(()) } /// ``` + #[must_use] pub fn version(&self) -> Option { self.version } @@ -438,24 +443,26 @@ impl Response { /// Sets a string representation of the peer address that this /// response was sent to. This might take the form of an ip/fqdn /// and port or a local socket address. - pub fn set_peer_addr(&mut self, peer_addr: Option) { + pub fn set_peer_addr(&mut self, peer_addr: Option) { self.peer_addr = peer_addr.map(|addr| addr.to_string()); } /// Sets a string representation of the local address that this /// response was sent on. This might take the form of an ip/fqdn and /// port, or a local socket address. - pub fn set_local_addr(&mut self, local_addr: Option) { + pub fn set_local_addr(&mut self, local_addr: Option) { self.local_addr = local_addr.map(|addr| addr.to_string()); } /// Get the peer socket address for the underlying transport, if appropriate + #[must_use] pub fn peer_addr(&self) -> Option<&str> { self.peer_addr.as_deref() } /// Get the local socket address for the underlying transport, if /// appropriate + #[must_use] pub fn local_addr(&self) -> Option<&str> { self.local_addr.as_deref() } @@ -503,6 +510,7 @@ impl Response { } /// Returns `true` if sending trailers is in progress. + #[must_use] pub fn has_trailers(&self) -> bool { self.has_trailers } @@ -520,7 +528,7 @@ impl Response { /// Receive an upgraded connection from a sender. #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - pub async fn recv_upgrade(&mut self) -> upgrade::Receiver { + pub fn recv_upgrade(&mut self) -> upgrade::Receiver { self.has_upgrade = true; let receiver = self .upgrade_receiver @@ -531,11 +539,13 @@ impl Response { /// Returns `true` if a protocol upgrade is in progress. #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + #[must_use] pub fn has_upgrade(&self) -> bool { self.has_upgrade } /// An iterator visiting all header pairs in arbitrary order. + #[must_use] pub fn iter(&self) -> headers::Iter<'_> { self.headers.iter() } @@ -547,16 +557,19 @@ impl Response { } /// An iterator visiting all header names in arbitrary order. + #[must_use] pub fn header_names(&self) -> Names<'_> { self.headers.names() } /// An iterator visiting all header values in arbitrary order. + #[must_use] pub fn header_values(&self) -> Values<'_> { self.headers.values() } /// Returns a reference to the existing local. + #[must_use] pub fn ext(&self) -> &Extensions { &self.ext } @@ -623,7 +636,7 @@ impl AsyncBufRead for Response { } fn consume(mut self: Pin<&mut Self>, amt: usize) { - Pin::new(&mut self.body).consume(amt) + Pin::new(&mut self.body).consume(amt); } } diff --git a/src/security/csp.rs b/src/security/csp.rs index 9478f34a..323bfdef 100644 --- a/src/security/csp.rs +++ b/src/security/csp.rs @@ -150,6 +150,7 @@ impl Default for ContentSecurityPolicy { impl ContentSecurityPolicy { /// Create a new instance. + #[must_use] pub fn new() -> Self { Self { policy: Vec::new(), @@ -282,15 +283,15 @@ impl ContentSecurityPolicy { /// /// [MDN | report-to](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to) #[cfg(feature = "serde")] - pub fn report_to(&mut self, endpoints: Vec) -> &mut Self { - for endpoint in endpoints.iter() { + pub fn report_to(&mut self, endpoints: &[ReportTo]) -> &mut Self { + for endpoint in endpoints { match serde_json::to_string(&endpoint) { Ok(json) => { - let policy = format!("report-to {}", json); + let policy = format!("report-to {json}"); self.policy.push(policy); } Err(error) => { - println!("{:?}", error); + println!("{error:?}"); } } } diff --git a/src/security/strict_transport_security.rs b/src/security/strict_transport_security.rs index f6c4fe4c..bc531a1b 100644 --- a/src/security/strict_transport_security.rs +++ b/src/security/strict_transport_security.rs @@ -23,7 +23,7 @@ impl Default for StrictTransportSecurity { /// [Read more](https://hstspreload.org/) fn default() -> Self { Self { - max_age: Duration::from_secs(31536000), // 1 year + max_age: Duration::from_secs(31_536_000), // 1 year include_subdomains: false, preload: true, } @@ -32,6 +32,7 @@ impl Default for StrictTransportSecurity { impl StrictTransportSecurity { /// Create a new instance. + #[must_use] pub fn new(duration: Duration) -> Self { Self { max_age: duration, @@ -40,6 +41,7 @@ impl StrictTransportSecurity { } } /// Get a reference to the strict transport security's include subdomains. + #[must_use] pub fn include_subdomains(&self) -> bool { self.include_subdomains } @@ -50,6 +52,7 @@ impl StrictTransportSecurity { } /// Get a reference to the strict transport security's preload. + #[must_use] pub fn preload(&self) -> bool { self.preload } @@ -59,12 +62,13 @@ impl StrictTransportSecurity { self.preload = preload; } - /// Get a reference to the strict transport security's max_age. + /// Get a reference to the strict transport security's `max_age`. + #[must_use] pub fn max_age(&self) -> Duration { self.max_age } - /// Set the strict transport security's max_age. + /// Set the strict transport security's `max_age`. pub fn set_max_age(&mut self, duration: Duration) { self.max_age = duration; } @@ -77,7 +81,7 @@ impl Header for StrictTransportSecurity { fn header_value(&self) -> HeaderValue { let max_age = self.max_age.as_secs(); - let mut output = format!("max-age={}", max_age); + let mut output = format!("max-age={max_age}"); if self.include_subdomains { output.push_str(";includeSubdomains"); } @@ -94,10 +98,7 @@ impl Header for StrictTransportSecurity { impl StrictTransportSecurity { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(STRICT_TRANSPORT_SECURITY) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(STRICT_TRANSPORT_SECURITY) else { return Ok(None) }; // If we successfully parsed the header then there's always at least one // entry. We want the last entry. @@ -116,10 +117,9 @@ impl StrictTransportSecurity { } else if s == "preload" { preload = true; } else { - let (key, value) = match s.split_once('=') { - Some(kv) => kv, - None => continue, // We don't recognize the directive, continue. - }; + let Some((key, value)) = s.split_once('=') else { + // We don't recognize the directive, continue. + continue }; if key == "max-age" { let secs = value.parse::().status(400)?; @@ -128,15 +128,12 @@ impl StrictTransportSecurity { } } - let max_age = match max_age { - Some(max_age) => max_age, - None => { - return Err(crate::format_err_status!( - 400, - "`Strict-Transport-Security` header did not contain a `max-age` directive", - )); - } - }; + let Some(max_age) = max_age else { + return Err(crate::format_err_status!( + 400, + "`Strict-Transport-Security` header did not contain a `max-age` directive", + )); + }; Ok(Some(Self { max_age, diff --git a/src/security/timing_allow_origin.rs b/src/security/timing_allow_origin.rs index 443427fb..81fb9f68 100644 --- a/src/security/timing_allow_origin.rs +++ b/src/security/timing_allow_origin.rs @@ -65,6 +65,7 @@ pub struct TimingAllowOrigin { impl TimingAllowOrigin { /// Create a new instance of `AllowOrigin`. + #[must_use] pub fn new() -> Self { Self { origins: vec![], @@ -78,10 +79,7 @@ impl TimingAllowOrigin { /// /// A header value of `"null"` is treated the same as if no header was sent. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(TIMING_ALLOW_ORIGIN) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(TIMING_ALLOW_ORIGIN) else { return Ok(None) }; let mut wildcard = false; let mut origins = vec![]; @@ -107,16 +105,18 @@ impl TimingAllowOrigin { } /// Returns `true` if a wildcard directive was set. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// An iterator visiting all server timings. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.origins.iter(), @@ -139,8 +139,8 @@ impl Header for TimingAllowOrigin { let mut output = String::new(); for (n, origin) in self.origins.iter().enumerate() { match n { - 0 => write!(output, "{}", origin).unwrap(), - _ => write!(output, ", {}", origin).unwrap(), + 0 => write!(output, "{origin}").unwrap(), + _ => write!(output, ", {origin}").unwrap(), }; } diff --git a/src/server/allow.rs b/src/server/allow.rs index 9377a3f6..502e2168 100644 --- a/src/server/allow.rs +++ b/src/server/allow.rs @@ -42,6 +42,7 @@ pub struct Allow { impl Allow { /// Create a new instance of `Allow`. + #[must_use] pub fn new() -> Self { Self { entries: HashSet::new(), @@ -51,10 +52,7 @@ impl Allow { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = HashSet::new(); - let headers = match headers.as_ref().get(ALLOW) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(ALLOW) else { return Ok(None) }; for value in headers { for part in value.as_str().trim().split(',') { @@ -72,6 +70,7 @@ impl Allow { } /// An iterator visiting all server entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -79,6 +78,7 @@ impl Allow { } /// Returns `true` if the header contains the `Method`. + #[must_use] pub fn contains(&self, method: Method) -> bool { self.entries.contains(&method) } @@ -92,8 +92,8 @@ impl Header for Allow { let mut output = String::new(); for (n, method) in self.entries.iter().enumerate() { match n { - 0 => write!(output, "{}", method).unwrap(), - _ => write!(output, ", {}", method).unwrap(), + 0 => write!(output, "{method}").unwrap(), + _ => write!(output, ", {method}").unwrap(), }; } diff --git a/src/status.rs b/src/status.rs index 59e6406e..eb53433f 100644 --- a/src/status.rs +++ b/src/status.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; /// Provides the `status` method for `Result` and `Option`. /// -/// This trait is sealed and cannot be implemented outside of `http-types`. +/// This trait is sealed and cannot be implemented outside `http-types`. pub trait Status: private::Sealed { /// Wrap the error value with an additional status code. fn status(self, status: S) -> Result @@ -32,8 +32,8 @@ where /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn status(self, status: S) -> Result where S: TryInto, @@ -54,8 +54,8 @@ where /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn with_status(self, f: F) -> Result where S: TryInto, @@ -78,8 +78,8 @@ impl Status for Result { /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn status(self, status: S) -> Result where S: TryInto, @@ -98,8 +98,8 @@ impl Status for Result { /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn with_status(self, f: F) -> Result where S: TryInto, @@ -120,8 +120,8 @@ impl Status for Option { /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn status(self, status: S) -> Result where S: TryInto, @@ -142,8 +142,8 @@ impl Status for Option { /// /// Panics if [`Status`][status] is not a valid [`StatusCode`][statuscode]. /// - /// [status]: crate::Status - /// [statuscode]: crate::StatusCode + /// [status]: Status + /// [statuscode]: StatusCode fn with_status(self, f: F) -> Result where S: TryInto, diff --git a/src/status_code.rs b/src/status_code.rs index 88141835..7b191a1c 100644 --- a/src/status_code.rs +++ b/src/status_code.rs @@ -424,6 +424,7 @@ impl StatusCode { /// /// If this returns `true` it indicates that the request was received, /// continuing process. + #[must_use] pub fn is_informational(&self) -> bool { let num: u16 = (*self).into(); (100..200).contains(&num) @@ -433,6 +434,7 @@ impl StatusCode { /// /// If this returns `true` it indicates that the request was successfully /// received, understood, and accepted. + #[must_use] pub fn is_success(&self) -> bool { let num: u16 = (*self).into(); (200..300).contains(&num) @@ -442,6 +444,7 @@ impl StatusCode { /// /// If this returns `true` it indicates that further action needs to be /// taken in order to complete the request. + #[must_use] pub fn is_redirection(&self) -> bool { let num: u16 = (*self).into(); (300..400).contains(&num) @@ -451,6 +454,7 @@ impl StatusCode { /// /// If this returns `true` it indicates that the request contains bad syntax /// or cannot be fulfilled. + #[must_use] pub fn is_client_error(&self) -> bool { let num: u16 = (*self).into(); (400..500).contains(&num) @@ -460,12 +464,14 @@ impl StatusCode { /// /// If this returns `true` it indicates that the server failed to fulfill an /// apparently valid request. + #[must_use] pub fn is_server_error(&self) -> bool { let num: u16 = (*self).into(); (500..600).contains(&num) } /// The canonical reason for a given status code + #[must_use] pub fn canonical_reason(&self) -> &'static str { match self { StatusCode::Continue => "Continue", @@ -586,7 +592,7 @@ mod serde { match StatusCode::try_from(v) { Ok(status_code) => Ok(status_code), Err(_) => Err(DeError::invalid_value( - Unexpected::Unsigned(v as u64), + Unexpected::Unsigned(u64::from(v)), &self, )), } diff --git a/src/trace/server_timing/metric.rs b/src/trace/server_timing/metric.rs index ed55c189..8a0ff364 100644 --- a/src/trace/server_timing/metric.rs +++ b/src/trace/server_timing/metric.rs @@ -37,16 +37,19 @@ impl Metric { } /// The timing name. + #[must_use] pub fn name(&self) -> &String { &self.name } /// The timing duration. + #[must_use] pub fn duration(&self) -> Option { self.dur } /// The timing description. + #[must_use] pub fn description(&self) -> Option<&str> { self.desc.as_deref() } @@ -61,10 +64,10 @@ impl From for HeaderValue { match (entry.dur, entry.desc) { (Some(dur), Some(desc)) => { - string.push_str(&format!("; dur={}; desc=\"{}\"", f(dur), desc)) + string.push_str(&format!("; dur={}; desc=\"{}\"", f(dur), desc)); } (Some(dur), None) => string.push_str(&format!("; dur={}", f(dur))), - (None, Some(desc)) => string.push_str(&format!("; desc=\"{}\"", desc)), + (None, Some(desc)) => string.push_str(&format!("; desc=\"{desc}\"")), (None, None) => {} }; diff --git a/src/trace/server_timing/mod.rs b/src/trace/server_timing/mod.rs index ddd6c79a..1d2408a0 100644 --- a/src/trace/server_timing/mod.rs +++ b/src/trace/server_timing/mod.rs @@ -67,6 +67,7 @@ pub struct ServerTiming { impl ServerTiming { /// Create a new instance of `ServerTiming`. + #[must_use] pub fn new() -> Self { Self { timings: vec![] } } @@ -74,10 +75,7 @@ impl ServerTiming { /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut timings = vec![]; - let headers = match headers.as_ref().get(SERVER_TIMING) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(SERVER_TIMING) else { return Ok(None) }; for value in headers { parse_header(value.as_str(), &mut timings)?; @@ -91,6 +89,7 @@ impl ServerTiming { } /// An iterator visiting all server timings. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.timings.iter(), @@ -115,8 +114,8 @@ impl Header for ServerTiming { for (n, timing) in self.timings.iter().enumerate() { let timing: HeaderValue = timing.clone().into(); match n { - 0 => write!(output, "{}", timing).unwrap(), - _ => write!(output, ", {}", timing).unwrap(), + 0 => write!(output, "{timing}").unwrap(), + _ => write!(output, ", {timing}").unwrap(), }; } diff --git a/src/trace/server_timing/parse.rs b/src/trace/server_timing/parse.rs index 4469336a..e6008e91 100644 --- a/src/trace/server_timing/parse.rs +++ b/src/trace/server_timing/parse.rs @@ -168,7 +168,7 @@ mod test { fn assert_entry_err(s: &str, msg: &str) { let err = parse_entry(s).unwrap_err(); - assert_eq!(format!("{}", err), msg); + assert_eq!(format!("{err}"), msg); } /// Assert an entry and all of its fields. diff --git a/src/trace/trace_context.rs b/src/trace/trace_context.rs index 3bc062f7..c0f4f790 100644 --- a/src/trace/trace_context.rs +++ b/src/trace/trace_context.rs @@ -44,9 +44,9 @@ pub struct TraceContext { } impl TraceContext { - /// Generate a new TraceContext object without a parent. + /// Generate a new `TraceContext` object without a parent. /// - /// By default root TraceContext objects are sampled. + /// By default root `TraceContext` objects are sampled. /// To mark it unsampled, call `context.set_sampled(false)`. /// /// # Examples @@ -58,6 +58,7 @@ impl TraceContext { /// assert_eq!(context.parent_id(), None); /// assert!(context.sampled()); /// ``` + #[must_use] pub fn new() -> Self { Self { id: fastrand::u64(..), @@ -68,7 +69,7 @@ impl TraceContext { } } - /// Create and return TraceContext object based on `traceparent` HTTP header. + /// Create and return `TraceContext` object based on `traceparent` HTTP header. /// /// # Errors /// @@ -102,10 +103,7 @@ impl TraceContext { pub fn from_headers(headers: impl AsRef) -> crate::Result> { let headers = headers.as_ref(); - let traceparent = match headers.get(TRACEPARENT) { - Some(header) => header, - None => return Ok(None), - }; + let Some(traceparent) = headers.get(TRACEPARENT) else { return Ok(None) }; let parts: Vec<&str> = traceparent.as_str().split('-').collect(); Ok(Some(Self { @@ -117,10 +115,11 @@ impl TraceContext { })) } - /// Generate a child of the current TraceContext and return it. + /// Generate a child of the current `TraceContext` and return it. /// - /// The child will have a new randomly genrated `id` and its `parent_id` will be set to the - /// `id` of this TraceContext. + /// The child will have a new randomly generated `id` and its `parent_id` will be set to the + /// `id` of this `TraceContext`. + #[must_use] pub fn child(&self) -> Self { Self { id: fastrand::u64(..), @@ -131,27 +130,31 @@ impl TraceContext { } } - /// Return the id of the TraceContext. + /// Return the id of the `TraceContext`. + #[must_use] pub fn id(&self) -> u64 { self.id } - /// Return the version of the TraceContext spec used. + /// Return the version of the `TraceContext` spec used. /// /// You probably don't need this. + #[must_use] pub fn version(&self) -> u8 { self.version } - /// Return the trace id of the TraceContext. + /// Return the trace id of the `TraceContext`. /// /// All children will have the same `trace_id`. + #[must_use] pub fn trace_id(&self) -> u128 { self.trace_id } - /// Return the id of the parent TraceContext. + /// Return the id of the parent `TraceContext`. #[inline] + #[must_use] pub fn parent_id(&self) -> Option { self.parent_id } @@ -173,8 +176,9 @@ impl TraceContext { /// # /// # Ok(()) } /// ``` + #[must_use] pub fn sampled(&self) -> bool { - (self.flags & 0b00000001) == 1 + (self.flags & 0b0000_0001) == 1 } /// Change sampled flag @@ -190,7 +194,7 @@ impl TraceContext { /// assert!(!context.sampled()); /// ``` pub fn set_sampled(&mut self, sampled: bool) { - let x = sampled as u8; + let x = u8::from(sampled); self.flags ^= (x ^ self.flags) & (1 << 0); } } @@ -201,7 +205,7 @@ impl Header for TraceContext { } fn header_value(&self) -> HeaderValue { - let output = format!("{}", self); + let output = format!("{self}"); unsafe { HeaderValue::from_bytes_unchecked(output.into()) } } } @@ -222,12 +226,12 @@ mod test { #[test] fn default() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = Headers::new(); headers.insert(TRACEPARENT, "00-01-deadbeef-00").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert_eq!(context.version(), 0); assert_eq!(context.trace_id(), 1); - assert_eq!(context.parent_id().unwrap(), 3735928559); + assert_eq!(context.parent_id().unwrap(), 3_735_928_559); assert_eq!(context.flags, 0); assert!(!context.sampled()); Ok(()) @@ -244,7 +248,7 @@ mod test { #[test] fn not_sampled() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = Headers::new(); headers.insert(TRACEPARENT, "00-01-02-00").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert!(!context.sampled()); @@ -253,7 +257,7 @@ mod test { #[test] fn sampled() -> crate::Result<()> { - let mut headers = crate::headers::Headers::new(); + let mut headers = Headers::new(); headers.insert(TRACEPARENT, "00-01-02-01").unwrap(); let context = TraceContext::from_headers(&mut headers)?.unwrap(); assert!(context.sampled()); diff --git a/src/trailers.rs b/src/trailers.rs index c65801c6..9d1b6f5c 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -67,6 +67,7 @@ pub struct Trailers { impl Trailers { /// Create a new instance of `Trailers`. + #[must_use] pub fn new() -> Self { Self { headers: Headers::new(), @@ -136,6 +137,7 @@ impl Trailers { } /// An iterator visiting all header pairs in arbitrary order. + #[must_use] pub fn iter(&self) -> Iter<'_> { self.headers.iter() } @@ -147,11 +149,13 @@ impl Trailers { } /// An iterator visiting all header names in arbitrary order. + #[must_use] pub fn names(&self) -> Names<'_> { self.headers.names() } /// An iterator visiting all header values in arbitrary order. + #[must_use] pub fn values(&self) -> Values<'_> { self.headers.values() } @@ -222,6 +226,7 @@ pub struct Sender { impl Sender { /// Create a new instance of `Sender`. #[doc(hidden)] + #[must_use] pub fn new(sender: async_channel::Sender) -> Self { Self { sender } } diff --git a/src/transfer/encoding_proposal.rs b/src/transfer/encoding_proposal.rs index 72f083d5..b3b4ac8b 100644 --- a/src/transfer/encoding_proposal.rs +++ b/src/transfer/encoding_proposal.rs @@ -27,7 +27,7 @@ impl EncodingProposal { ensure!( weight.is_sign_positive() && weight <= 1.0, "EncodingProposal should have a weight between 0.0 and 1.0" - ) + ); } Ok(Self { @@ -37,21 +37,20 @@ impl EncodingProposal { } /// Get the proposed encoding. + #[must_use] pub fn encoding(&self) -> &Encoding { &self.encoding } /// Get the weight of the proposal. + #[must_use] pub fn weight(&self) -> Option { self.weight } pub(crate) fn from_str(s: &str) -> crate::Result> { let mut parts = s.split(';'); - let encoding = match Encoding::from_str(parts.next().unwrap()) { - Some(encoding) => encoding, - None => return Ok(None), - }; + let Some(encoding) = Encoding::from_str(parts.next().unwrap()) else { return Ok(None) }; let weight = parts.next().map(parse_weight).transpose()?; Ok(Some(Self::new(encoding, weight)?)) @@ -100,7 +99,7 @@ impl DerefMut for EncodingProposal { // NOTE: This comparison does not include a notion of `*` (any value is valid). // that needs to be handled separately. impl PartialOrd for EncodingProposal { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { match (self.weight, other.weight) { (Some(left), Some(right)) => left.partial_cmp(&right), (Some(_), None) => Some(Ordering::Greater), diff --git a/src/transfer/te.rs b/src/transfer/te.rs index acd1af80..08fd6f60 100644 --- a/src/transfer/te.rs +++ b/src/transfer/te.rs @@ -44,6 +44,7 @@ pub struct TE { impl TE { /// Create a new instance of `TE`. + #[must_use] pub fn new() -> Self { Self { entries: vec![], @@ -54,10 +55,7 @@ impl TE { /// Create an instance of `TE` from a `Headers` instance. pub fn from_headers(headers: impl AsRef) -> crate::Result> { let mut entries = vec![]; - let headers = match headers.as_ref().get(headers::TE) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(headers::TE) else { return Ok(None) }; let mut wildcard = false; @@ -65,16 +63,18 @@ impl TE { for part in value.as_str().trim().split(',') { let part = part.trim(); - // Handle empty strings, and wildcard directives. + // Handle empty strings. if part.is_empty() { continue; - } else if part == "*" { + } + // Handle wildcard directives. + if part == "*" { wildcard = true; continue; } // Try and parse a directive from a str. If the directive is - // unkown we skip it. + // unknown we skip it. if let Some(entry) = EncodingProposal::from_str(part)? { entries.push(entry); } @@ -90,13 +90,14 @@ impl TE { } /// Returns `true` if a wildcard directive was passed. + #[must_use] pub fn wildcard(&self) -> bool { self.wildcard } /// Set the wildcard directive. pub fn set_wildcard(&mut self, wildcard: bool) { - self.wildcard = wildcard + self.wildcard = wildcard; } /// Sort the header directives by weight. @@ -137,6 +138,7 @@ impl TE { } /// An iterator visiting all entries. + #[must_use] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.entries.iter(), @@ -161,8 +163,8 @@ impl Header for TE { for (n, directive) in self.entries.iter().enumerate() { let directive: HeaderValue = (*directive).into(); match n { - 0 => write!(output, "{}", directive).unwrap(), - _ => write!(output, ", {}", directive).unwrap(), + 0 => write!(output, "{directive}").unwrap(), + _ => write!(output, ", {directive}").unwrap(), }; } diff --git a/src/transfer/transfer_encoding.rs b/src/transfer/transfer_encoding.rs index 7fede4aa..a20c73ba 100644 --- a/src/transfer/transfer_encoding.rs +++ b/src/transfer/transfer_encoding.rs @@ -35,16 +35,14 @@ pub struct TransferEncoding { impl TransferEncoding { /// Create a new instance of `CacheControl`. + #[must_use] pub fn new(encoding: Encoding) -> Self { Self { inner: encoding } } /// Create a new instance from headers. pub fn from_headers(headers: impl AsRef) -> crate::Result> { - let headers = match headers.as_ref().get(TRANSFER_ENCODING) { - Some(headers) => headers, - None => return Ok(None), - }; + let Some(headers) = headers.as_ref().get(TRANSFER_ENCODING) else { return Ok(None) }; let mut inner = None; @@ -59,6 +57,7 @@ impl TransferEncoding { } /// Access the encoding kind. + #[must_use] pub fn encoding(&self) -> Encoding { self.inner } diff --git a/src/upgrade/sender.rs b/src/upgrade/sender.rs index a95b7675..d093f718 100644 --- a/src/upgrade/sender.rs +++ b/src/upgrade/sender.rs @@ -13,6 +13,7 @@ pub struct Sender { impl Sender { /// Create a new instance of `Sender`. #[doc(hidden)] + #[must_use] pub fn new(sender: async_channel::Sender) -> Self { Self { sender } } diff --git a/src/utils/date.rs b/src/utils/date.rs index 7f9f382b..ca8f809c 100644 --- a/src/utils/date.rs +++ b/src/utils/date.rs @@ -9,7 +9,7 @@ const IMF_FIXDATE_LENGTH: usize = 29; const RFC850_MAX_LENGTH: usize = 23; const ASCTIME_LENGTH: usize = 24; -const YEAR_9999_SECONDS: u64 = 253402300800; +const YEAR_9999_SECONDS: u64 = 253_402_300_800; const SECONDS_IN_DAY: u64 = 86400; const SECONDS_IN_HOUR: u64 = 3600; @@ -40,10 +40,12 @@ pub(crate) struct HttpDate { /// ascdate formats. Two digit years are mapped to dates between /// 1970 and 2069. pub(crate) fn parse_http_date(s: &str) -> crate::Result { - s.parse::().map(|d| d.into()).map_err(|mut e| { - e.set_status(StatusCode::BadRequest); - e - }) + s.parse::() + .map(std::convert::Into::into) + .map_err(|mut e| { + e.set_status(StatusCode::BadRequest); + e + }) } /// Format a date to be used in a HTTP header field. @@ -262,7 +264,7 @@ impl From for HttpDate { let months = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29]; let mut month = 0; - for month_len in months.iter() { + for month_len in &months { month += 1; if remdays < *month_len { break; @@ -279,7 +281,7 @@ impl From for HttpDate { let mut week_day = (3 + days) % 7; if week_day <= 0 { - week_day += 7 + week_day += 7; }; HttpDate { @@ -312,17 +314,17 @@ impl From for SystemTime { 11 => 304, 12 => 334, _ => unreachable!(), - } + http_date.day as u64 + } + u64::from(http_date.day) - 1; if is_leap_year(http_date.year) && http_date.month > 2 { ydays += 1; } - let days = (http_date.year as u64 - 1970) * 365 + leap_years as u64 + ydays; + let days = (u64::from(http_date.year) - 1970) * 365 + u64::from(leap_years) + ydays; UNIX_EPOCH + Duration::from_secs( - http_date.second as u64 - + http_date.minute as u64 * 60 - + http_date.hour as u64 * SECONDS_IN_HOUR + u64::from(http_date.second) + + u64::from(http_date.minute) * 60 + + u64::from(http_date.hour) * SECONDS_IN_HOUR + days * SECONDS_IN_DAY, ) } @@ -378,8 +380,8 @@ impl Display for HttpDate { buf[0] = week_day[0]; buf[1] = week_day[1]; buf[2] = week_day[2]; - buf[5] = b'0' + (self.day / 10) as u8; - buf[6] = b'0' + (self.day % 10) as u8; + buf[5] = b'0' + (self.day / 10); + buf[6] = b'0' + (self.day % 10); buf[8] = month[0]; buf[9] = month[1]; buf[10] = month[2]; @@ -387,12 +389,12 @@ impl Display for HttpDate { buf[13] = b'0' + (self.year / 100 % 10) as u8; buf[14] = b'0' + (self.year / 10 % 10) as u8; buf[15] = b'0' + (self.year % 10) as u8; - buf[17] = b'0' + (self.hour / 10) as u8; - buf[18] = b'0' + (self.hour % 10) as u8; - buf[20] = b'0' + (self.minute / 10) as u8; - buf[21] = b'0' + (self.minute % 10) as u8; - buf[23] = b'0' + (self.second / 10) as u8; - buf[24] = b'0' + (self.second % 10) as u8; + buf[17] = b'0' + (self.hour / 10); + buf[18] = b'0' + (self.hour % 10); + buf[20] = b'0' + (self.minute / 10); + buf[21] = b'0' + (self.minute % 10); + buf[23] = b'0' + (self.second / 10); + buf[24] = b'0' + (self.second % 10); f.write_str(from_utf8(&buf[..]).unwrap()) } } @@ -421,7 +423,7 @@ mod tests { #[test] fn test_rfc_example() { - let d = UNIX_EPOCH + Duration::from_secs(784111777); + let d = UNIX_EPOCH + Duration::from_secs(784_111_777); assert_eq!( d, parse_http_date("Sun, 06 Nov 1994 08:49:37 GMT").expect("#1") @@ -435,7 +437,7 @@ mod tests { #[test] fn test2() { - let d = UNIX_EPOCH + Duration::from_secs(1475419451); + let d = UNIX_EPOCH + Duration::from_secs(1_475_419_451); assert_eq!( d, parse_http_date("Sun, 02 Oct 2016 14:44:11 GMT").expect("#1") @@ -453,17 +455,17 @@ mod tests { assert_eq!(d, parse_http_date("Thu, 01 Jan 1970 01:00:00 GMT").unwrap()); d += Duration::from_secs(SECONDS_IN_DAY); assert_eq!(d, parse_http_date("Fri, 02 Jan 1970 01:00:00 GMT").unwrap()); - d += Duration::from_secs(2592000); + d += Duration::from_secs(2_592_000); assert_eq!(d, parse_http_date("Sun, 01 Feb 1970 01:00:00 GMT").unwrap()); - d += Duration::from_secs(2592000); + d += Duration::from_secs(2_592_000); assert_eq!(d, parse_http_date("Tue, 03 Mar 1970 01:00:00 GMT").unwrap()); - d += Duration::from_secs(31536005); + d += Duration::from_secs(31_536_005); assert_eq!(d, parse_http_date("Wed, 03 Mar 1971 01:00:05 GMT").unwrap()); - d += Duration::from_secs(15552000); + d += Duration::from_secs(15_552_000); assert_eq!(d, parse_http_date("Mon, 30 Aug 1971 01:00:05 GMT").unwrap()); - d += Duration::from_secs(6048000); + d += Duration::from_secs(6_048_000); assert_eq!(d, parse_http_date("Mon, 08 Nov 1971 01:00:05 GMT").unwrap()); - d += Duration::from_secs(864000000); + d += Duration::from_secs(864_000_000); assert_eq!(d, parse_http_date("Fri, 26 Mar 1999 01:00:05 GMT").unwrap()); } @@ -471,12 +473,12 @@ mod tests { fn test_fmt() { let d = UNIX_EPOCH; assert_eq!(fmt_http_date(d), "Thu, 01 Jan 1970 00:00:00 GMT"); - let d = UNIX_EPOCH + Duration::from_secs(1475419451); + let d = UNIX_EPOCH + Duration::from_secs(1_475_419_451); assert_eq!(fmt_http_date(d), "Sun, 02 Oct 2016 14:44:11 GMT"); } #[test] fn size_of() { - assert_eq!(::std::mem::size_of::(), 8); + assert_eq!(std::mem::size_of::(), 8); } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 9c9ea923..3093372c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -17,16 +17,13 @@ pub(crate) fn parse_weight(s: &str) -> crate::Result { err.set_status(StatusCode::BadRequest); return Err(err); } - match parts.next() { - Some(s) => { - let weight = f32::from_str(s).status(400)?; - Ok(weight) - } - None => { - let mut err = Error::new_adhoc("invalid weight"); - err.set_status(StatusCode::BadRequest); - Err(err) - } + if let Some(s) = parts.next() { + let weight = f32::from_str(s).status(400)?; + Ok(weight) + } else { + let mut err = Error::new_adhoc("invalid weight"); + err.set_status(StatusCode::BadRequest); + Err(err) } } diff --git a/src/version.rs b/src/version.rs index a6343ffa..e5f942ba 100644 --- a/src/version.rs +++ b/src/version.rs @@ -122,7 +122,7 @@ mod test { #[test] fn ord() { - use Version::*; + use Version::{Http0_9, Http1_0, Http1_1, Http2_0, Http3_0}; assert!(Http3_0 > Http2_0); assert!(Http2_0 > Http1_1); assert!(Http1_1 > Http1_0); diff --git a/tests/error.rs b/tests/error.rs index 4cf97923..9f0763fc 100644 --- a/tests/error.rs +++ b/tests/error.rs @@ -73,26 +73,23 @@ fn option_ext() { #[test] fn anyhow_error_into_http_types_error() { - let anyhow_error = - anyhow::Error::new(std::io::Error::new(std::io::ErrorKind::Other, "irrelevant")); + let anyhow_error = anyhow::Error::new(io::Error::new(io::ErrorKind::Other, "irrelevant")); let http_types_error: Error = anyhow_error.into(); assert_eq!(http_types_error.status(), StatusCode::InternalServerError); - let anyhow_error = - anyhow::Error::new(std::io::Error::new(std::io::ErrorKind::Other, "irrelevant")); + let anyhow_error = anyhow::Error::new(io::Error::new(io::ErrorKind::Other, "irrelevant")); let http_types_error: Error = Error::new(StatusCode::ImATeapot, anyhow_error); assert_eq!(http_types_error.status(), StatusCode::ImATeapot); } #[test] fn normal_error_into_http_types_error() { - let http_types_error: Error = - std::io::Error::new(std::io::ErrorKind::Other, "irrelevant").into(); + let http_types_error: Error = io::Error::new(io::ErrorKind::Other, "irrelevant").into(); assert_eq!(http_types_error.status(), StatusCode::InternalServerError); let http_types_error = Error::new( StatusCode::ImATeapot, - std::io::Error::new(std::io::ErrorKind::Other, "irrelevant"), + io::Error::new(io::ErrorKind::Other, "irrelevant"), ); assert_eq!(http_types_error.status(), StatusCode::ImATeapot); }