style: warn on more pedantic clippy lints and fix them (#1035)
This commit is contained in:
@@ -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>;
|
||||
|
||||
@@ -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))]
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}")?;
|
||||
|
||||
@@ -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}")?;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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}")?;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,7 @@ mod tests {
|
||||
("bjørn", "bjørn"),
|
||||
("Ø+= ❤️‰", "Ø+2B+3D+20❤️‰"),
|
||||
("+", "+2B"),
|
||||
]
|
||||
.iter()
|
||||
{
|
||||
] {
|
||||
assert_eq!(format!("{}", XText(input)), (*expect).to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user