style: warn on more pedantic clippy lints and fix them (#1035)

This commit is contained in:
Paolo Barbolini
2025-02-02 12:50:15 +01:00
committed by GitHub
parent 5f13636b49
commit bb64baec67
17 changed files with 59 additions and 56 deletions

View File

@@ -29,7 +29,7 @@ pub struct Envelope {
mod serde_forward_path {
use super::Address;
/// dummy type required for serde
/// see example: https://serde.rs/deserialize-map.html
/// see example: <https://serde.rs/deserialize-map.html>
struct CustomVisitor;
impl<'de> serde::de::Visitor<'de> for CustomVisitor {
type Value = Vec<Address>;

View File

@@ -149,7 +149,14 @@
clippy::wildcard_imports,
clippy::str_to_string,
clippy::empty_structs_with_brackets,
clippy::zero_sized_map_values
clippy::zero_sized_map_values,
clippy::manual_let_else,
clippy::semicolon_if_nothing_returned,
clippy::unnecessary_wraps,
clippy::doc_markdown,
clippy::explicit_iter_loop,
clippy::redundant_closure_for_method_calls,
// Rust 1.86: clippy::unnecessary_semicolon,
)]
#![cfg_attr(docsrs, feature(doc_cfg))]

View File

@@ -69,7 +69,7 @@ impl Display for DkimSigningAlgorithm {
}
}
/// Describe DkimSigning key error
/// Describe [`DkimSigning`] key error
#[derive(Debug)]
pub struct DkimSigningKeyError(InnerDkimSigningKeyError);
@@ -100,7 +100,7 @@ impl StdError for DkimSigningKeyError {
}
}
/// Describe a signing key to be carried by DkimConfig struct
/// Describe a signing key to be carried by [`DkimConfig`] struct
#[derive(Debug)]
pub struct DkimSigningKey(InnerDkimSigningKey);
@@ -183,7 +183,7 @@ impl DkimConfig {
}
}
/// Create a DkimConfig
/// Create a [`DkimConfig`]
pub fn new(
selector: String,
domain: String,
@@ -283,19 +283,19 @@ fn dkim_canonicalize_headers_relaxed(headers: &str) -> String {
// End of header.
[b'\r', b'\n', ..] => {
*out += "\r\n";
name(&h[2..], out)
name(&h[2..], out);
}
// Sequential whitespace.
[b' ' | b'\t', b' ' | b'\t' | b'\r', ..] => value(&h[1..], out),
// All whitespace becomes spaces.
[b'\t', ..] => {
out.push(' ');
value(&h[1..], out)
value(&h[1..], out);
}
[_, ..] => {
let mut chars = h.chars();
out.push(chars.next().unwrap());
value(chars.as_str(), out)
value(chars.as_str(), out);
}
[] => {}
}
@@ -317,7 +317,7 @@ fn dkim_canonicalize_header_tag(
}
}
/// Canonicalize signed headers passed as headers_list among mail_headers using canonicalization
/// Canonicalize signed headers passed as `headers_list` among `mail_headers` using canonicalization
fn dkim_canonicalize_headers<'a>(
headers_list: impl IntoIterator<Item = &'a str>,
mail_headers: &Headers,
@@ -344,9 +344,9 @@ fn dkim_canonicalize_headers<'a>(
}
/// Sign with Dkim a message by adding Dkim-Signature header created with configuration expressed by
/// dkim_config
/// `dkim_config`
pub fn dkim_sign(message: &mut Message, dkim_config: &DkimConfig) {
dkim_sign_fixed_time(message, dkim_config, SystemTime::now())
dkim_sign_fixed_time(message, dkim_config, SystemTime::now());
}
fn dkim_sign_fixed_time(message: &mut Message, dkim_config: &DkimConfig, timestamp: SystemTime) {
@@ -377,7 +377,7 @@ fn dkim_sign_fixed_time(message: &mut Message, dkim_config: &DkimConfig, timesta
}
let dkim_header = dkim_header_format(dkim_config, timestamp, &signed_headers_list, &bh, "");
let signed_headers = dkim_canonicalize_headers(
dkim_config.headers.iter().map(|h| h.as_ref()),
dkim_config.headers.iter().map(AsRef::as_ref),
headers,
dkim_config.canonicalization.header,
);
@@ -487,14 +487,14 @@ cJ5Ku0OTwRtSMaseRPX+T4EfG1Caa/eunPPN4rh+CSup2BVVarOT
fn test_headers_simple_canonicalize() {
let message = test_message();
dbg!(message.headers.to_string());
assert_eq!(dkim_canonicalize_headers(["From", "Test"], &message.headers, DkimCanonicalizationType::Simple), "From: =?utf-8?b?VGVzdCBPJ0xlYXJ5?= <test+ezrz@example.net>\r\nTest: test test very very long with spaces and extra spaces \twill be\r\n folded to several lines \r\n")
assert_eq!(dkim_canonicalize_headers(["From", "Test"], &message.headers, DkimCanonicalizationType::Simple), "From: =?utf-8?b?VGVzdCBPJ0xlYXJ5?= <test+ezrz@example.net>\r\nTest: test test very very long with spaces and extra spaces \twill be\r\n folded to several lines \r\n");
}
#[test]
fn test_headers_relaxed_canonicalize() {
let message = test_message();
dbg!(message.headers.to_string());
assert_eq!(dkim_canonicalize_headers(["From", "Test"], &message.headers, DkimCanonicalizationType::Relaxed),"from:=?utf-8?b?VGVzdCBPJ0xlYXJ5?= <test+ezrz@example.net>\r\ntest:test test very very long with spaces and extra spaces will be folded to several lines\r\n")
assert_eq!(dkim_canonicalize_headers(["From", "Test"], &message.headers, DkimCanonicalizationType::Relaxed),"from:=?utf-8?b?VGVzdCBPJ0xlYXJ5?= <test+ezrz@example.net>\r\ntest:test test very very long with spaces and extra spaces will be folded to several lines\r\n");
}
#[test]

View File

@@ -415,7 +415,7 @@ mod tests {
#[test]
fn empty_headername() {
assert!(HeaderName::new_from_ascii(String::from("")).is_err());
assert!(HeaderName::new_from_ascii("".to_owned()).is_err());
}
#[test]

View File

@@ -351,7 +351,7 @@ impl FromStr for Mailboxes {
})?;
for (name, (user, domain)) in parsed_mailboxes {
mailboxes.push(Mailbox::new(name, Address::new(user, domain)?))
mailboxes.push(Mailbox::new(name, Address::new(user, domain)?));
}
Ok(Mailboxes(mailboxes))
@@ -531,7 +531,7 @@ mod test {
assert_eq!(
format!(
"{}",
Mailbox::new(Some("".into()), "kayo@example.com".parse().unwrap())
Mailbox::new(Some("".to_owned()), "kayo@example.com".parse().unwrap())
),
"kayo@example.com"
);

View File

@@ -527,7 +527,7 @@ impl Message {
match &self.body {
MessageBody::Mime(p) => p.format_body(&mut out),
MessageBody::Raw(r) => out.extend_from_slice(r),
};
}
out.extend_from_slice(b"\r\n");
out
}
@@ -605,7 +605,7 @@ impl EmailFormat for Message {
MessageBody::Mime(p) => p.format(out),
MessageBody::Raw(r) => {
out.extend_from_slice(b"\r\n");
out.extend_from_slice(r)
out.extend_from_slice(r);
}
}
}
@@ -769,7 +769,7 @@ mod test {
continue;
}
assert_eq!(line.0, line.1)
assert_eq!(line.0, line.1);
}
}

View File

@@ -68,7 +68,7 @@ impl fmt::Display for Error {
Kind::Io => f.write_str("response error")?,
#[cfg(feature = "file-transport-envelope")]
Kind::Envelope => f.write_str("internal client error")?,
};
}
if let Some(e) = &self.inner.source {
write!(f, ": {e}")?;

View File

@@ -65,7 +65,7 @@ impl fmt::Display for Error {
match self.inner.kind {
Kind::Response => f.write_str("response error")?,
Kind::Client => f.write_str("internal client error")?,
};
}
if let Some(e) = &self.inner.source {
write!(f, ": {e}")?;

View File

@@ -123,7 +123,7 @@ impl SendmailTransport {
/// Creates a new transport with the `sendmail` command
///
/// Note: This uses the `sendmail` command in the current `PATH`. To use another command,
/// use [SendmailTransport::new_with_command].
/// use [`SendmailTransport::new_with_command`].
pub fn new() -> SendmailTransport {
SendmailTransport {
command: DEFAULT_SENDMAIL.into(),
@@ -160,7 +160,7 @@ where
/// Creates a new transport with the `sendmail` command
///
/// Note: This uses the `sendmail` command in the current `PATH`. To use another command,
/// use [AsyncSendmailTransport::new_with_command].
/// use [`AsyncSendmailTransport::new_with_command`].
pub fn new() -> Self {
Self {
inner: SendmailTransport::new(),

View File

@@ -170,7 +170,7 @@ impl AsyncNetworkStream {
last_err = Some(io::Error::new(
io::ErrorKind::TimedOut,
"connection timed out",
))
));
}
}
} else {
@@ -222,7 +222,7 @@ impl AsyncNetworkStream {
last_err = Some(io::Error::new(
io::ErrorKind::TimedOut,
"connection timed out",
))
));
}
}
}
@@ -270,9 +270,8 @@ impl AsyncNetworkStream {
InnerAsyncNetworkStream::Tokio1Tcp(_) => {
// get owned TcpStream
let tcp_stream = mem::replace(&mut self.inner, InnerAsyncNetworkStream::None);
let tcp_stream = match tcp_stream {
InnerAsyncNetworkStream::Tokio1Tcp(tcp_stream) => tcp_stream,
_ => unreachable!(),
let InnerAsyncNetworkStream::Tokio1Tcp(tcp_stream) = tcp_stream else {
unreachable!()
};
self.inner = Self::upgrade_tokio1_tls(tcp_stream, tls_parameters)
@@ -290,9 +289,8 @@ impl AsyncNetworkStream {
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
// get owned TcpStream
let tcp_stream = mem::replace(&mut self.inner, InnerAsyncNetworkStream::None);
let tcp_stream = match tcp_stream {
InnerAsyncNetworkStream::AsyncStd1Tcp(tcp_stream) => tcp_stream,
_ => unreachable!(),
let InnerAsyncNetworkStream::AsyncStd1Tcp(tcp_stream) = tcp_stream else {
unreachable!()
};
self.inner = Self::upgrade_asyncstd1_tls(tcp_stream, tls_parameters)

View File

@@ -160,9 +160,8 @@ impl NetworkStream {
InnerNetworkStream::Tcp(_) => {
// get owned TcpStream
let tcp_stream = mem::replace(&mut self.inner, InnerNetworkStream::None);
let tcp_stream = match tcp_stream {
InnerNetworkStream::Tcp(tcp_stream) => tcp_stream,
_ => unreachable!(),
let InnerNetworkStream::Tcp(tcp_stream) = tcp_stream else {
unreachable!()
};
self.inner = Self::upgrade_tls_impl(tcp_stream, tls_parameters)?;

View File

@@ -423,7 +423,7 @@ impl TlsParametersBuilder {
let mut root_cert_store = RootCertStore::empty();
#[cfg(feature = "rustls-native-certs")]
fn load_native_roots(store: &mut RootCertStore) -> Result<(), Error> {
fn load_native_roots(store: &mut RootCertStore) {
let rustls_native_certs::CertificateResult { certs, errors, .. } =
rustls_native_certs::load_native_certs();
let errors_len = errors.len();
@@ -433,7 +433,6 @@ impl TlsParametersBuilder {
tracing::debug!(
"loaded platform certs with {errors_len} failing to load, {added} valid and {ignored} ignored (invalid) certs"
);
Ok(())
}
#[cfg(feature = "rustls-tls")]
@@ -444,7 +443,7 @@ impl TlsParametersBuilder {
match self.cert_store {
CertificateStore::Default => {
#[cfg(feature = "rustls-native-certs")]
load_native_roots(&mut root_cert_store)?;
load_native_roots(&mut root_cert_store);
#[cfg(not(feature = "rustls-native-certs"))]
load_webpki_roots(&mut root_cert_store);
}
@@ -662,10 +661,11 @@ impl Identity {
#[cfg(feature = "rustls-tls")]
fn from_pem_rustls_tls(
pem: &[u8],
key: &[u8],
mut key: &[u8],
) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>), Error> {
let mut key = key;
let key = rustls_pemfile::private_key(&mut key).unwrap().unwrap();
let key = rustls_pemfile::private_key(&mut key)
.map_err(error::tls)?
.ok_or_else(|| error::tls("no private key found"))?;
Ok((vec![pem.to_owned().into()], key))
}

View File

@@ -1,3 +1,5 @@
use std::borrow::Cow;
use url::Url;
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
@@ -84,26 +86,26 @@ pub(crate) fn from_connection_url<B: TransportBuilder>(connection_url: &str) ->
("smtp", Some("required")) => {
builder = builder
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
.tls(Tls::Required(TlsParameters::new(host.into())?))
.tls(Tls::Required(TlsParameters::new(host.into())?));
}
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
("smtp", Some("opportunistic")) => {
builder = builder
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
.tls(Tls::Opportunistic(TlsParameters::new(host.into())?))
.tls(Tls::Opportunistic(TlsParameters::new(host.into())?));
}
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
("smtps", _) => {
builder = builder
.port(connection_url.port().unwrap_or(SUBMISSIONS_PORT))
.tls(Tls::Wrapper(TlsParameters::new(host.into())?))
.tls(Tls::Wrapper(TlsParameters::new(host.into())?));
}
(scheme, tls) => {
return Err(error::connection(format!(
"Unknown scheme '{scheme}' or tls parameter '{tls:?}', note that a transport with TLS requires one of the TLS features"
)))
}
};
}
// use the path segment of the URL as name in the name in the HELO / EHLO command
if connection_url.path().len() > 1 {
@@ -115,7 +117,7 @@ pub(crate) fn from_connection_url<B: TransportBuilder>(connection_url: &str) ->
let percent_decode = |s: &str| {
percent_encoding::percent_decode_str(s)
.decode_utf8()
.map(|cow| cow.into_owned())
.map(Cow::into_owned)
.map_err(error::connection)
};
let credentials = Credentials::new(

View File

@@ -142,7 +142,7 @@ impl fmt::Display for Error {
Kind::Permanent(code) => {
write!(f, "permanent error ({code})")?;
}
};
}
if let Some(e) = &self.inner.source {
write!(f, ": {e}")?;

View File

@@ -129,9 +129,8 @@ impl Display for ServerInfo {
impl ServerInfo {
/// Parses a EHLO response to create a `ServerInfo`
pub fn from_response(response: &Response) -> Result<ServerInfo, Error> {
let name = match response.first_word() {
Some(name) => name,
None => return Err(error::response("Could not read server name")),
let Some(name) = response.first_word() else {
return Err(error::response("Could not read server name"));
};
let mut features: HashSet<Extension> = HashSet::new();
@@ -169,7 +168,7 @@ impl ServerInfo {
}
}
_ => (),
};
}
}
Ok(ServerInfo {

View File

@@ -109,7 +109,7 @@ impl<E: Executor> Pool<E> {
#[cfg(feature = "tracing")]
tracing::debug!("dropped {} idle connections", dropped.len());
abort_concurrent(dropped.into_iter().map(|conn| conn.unpark()))
abort_concurrent(dropped.into_iter().map(ParkedConnection::unpark))
.await;
}
}
@@ -229,7 +229,7 @@ impl<E: Executor> Drop for Pool<E> {
handle.shutdown().await;
}
abort_concurrent(connections.into_iter().map(|conn| conn.unpark())).await;
abort_concurrent(connections.into_iter().map(ParkedConnection::unpark)).await;
});
}
}

View File

@@ -38,9 +38,7 @@ mod tests {
("bjørn", "bjørn"),
("Ø+= ❤️‰", "Ø+2B+3D+20❤"),
("+", "+2B"),
]
.iter()
{
] {
assert_eq!(format!("{}", XText(input)), (*expect).to_owned());
}
}