From 477de69ca3499ca57088830c9d94c65ad5eb4719 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 29 May 2023 11:33:36 -0400 Subject: [PATCH] Added Connection and connection::Builder; Fixed a lot of Clippy lints; --- src/connection/builder.rs | 35 +++++++++++++++++++++++++++++++++++ src/connection/error.rs | 1 + src/connection/mod.rs | 8 ++++++++ src/connection/verifier.rs | 7 +++++++ src/fingerprint/mod.rs | 2 +- src/host/mod.rs | 2 +- src/lib.rs | 1 + src/mailbox/mod.rs | 19 +++++++++---------- src/mailstore/filesystem.rs | 9 ++++----- src/mailstore/mod.rs | 11 +++++------ src/message/mod.rs | 4 ++-- src/request/mod.rs | 19 +++++++++---------- src/sender/verifier.rs | 12 ++++++------ 13 files changed, 89 insertions(+), 41 deletions(-) create mode 100644 src/connection/builder.rs create mode 100644 src/connection/error.rs create mode 100644 src/connection/mod.rs create mode 100644 src/connection/verifier.rs diff --git a/src/connection/builder.rs b/src/connection/builder.rs new file mode 100644 index 0000000..84170f6 --- /dev/null +++ b/src/connection/builder.rs @@ -0,0 +1,35 @@ +use super::verifier::Verifier; +use crate::prelude::CertificateStore; +use std::net::TcpStream; + +#[derive(Debug)] +pub struct Builder { + pub stream: Option, + pub verifier: Option>, +} + +impl Default for Builder { + fn default() -> Self { + Self { stream: None, verifier: None } + } +} + +impl Builder { + pub fn new() -> Self { + Self::default() + } + + pub fn stream(mut self, stream: TcpStream) -> Self { + self.stream = Some(stream); + self + } + + pub fn verifier(mut self, verifier: Verifier) -> Self { + self.verifier = Some(verifier); + self + } + + pub fn build(self) -> super::Connection { + todo!() + } +} diff --git a/src/connection/error.rs b/src/connection/error.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/connection/error.rs @@ -0,0 +1 @@ + diff --git a/src/connection/mod.rs b/src/connection/mod.rs new file mode 100644 index 0000000..c420bff --- /dev/null +++ b/src/connection/mod.rs @@ -0,0 +1,8 @@ +pub mod builder; +pub mod error; +pub mod verifier; + +#[derive(Debug)] +pub struct Connection { + pub inner: rustls::ServerConnection, +} diff --git a/src/connection/verifier.rs b/src/connection/verifier.rs new file mode 100644 index 0000000..e16c01a --- /dev/null +++ b/src/connection/verifier.rs @@ -0,0 +1,7 @@ +use crate::prelude::CertificateStore; +use std::sync::Mutex; + +#[derive(Debug)] +pub struct Verifier { + pub store: Mutex, +} diff --git a/src/fingerprint/mod.rs b/src/fingerprint/mod.rs index 25926dd..0b48e8c 100644 --- a/src/fingerprint/mod.rs +++ b/src/fingerprint/mod.rs @@ -31,7 +31,7 @@ impl GetFingerprint for Certificate { subject.iter_common_name().for_each(|n| { let mut val = n.attr_value().data; let mut name = String::new(); - if let Ok(_) = val.read_to_string(&mut name) { + if val.read_to_string(&mut name).is_ok() { names.push(name); } }); diff --git a/src/host/mod.rs b/src/host/mod.rs index c2ec8ef..a7c1340 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -80,7 +80,7 @@ impl ToSocketAddrs for Host { type Iter = std::vec::IntoIter; fn to_socket_addrs(&self) -> std::io::Result { - format!("{}:1958", self).to_socket_addrs() + format!("{self}:1958").to_socket_addrs() } } diff --git a/src/lib.rs b/src/lib.rs index d7ba3c4..bea027e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![warn(clippy::all, clippy::pedantic)] pub mod certificate; +pub mod connection; pub mod fingerprint; pub mod host; pub mod mailbox; diff --git a/src/mailbox/mod.rs b/src/mailbox/mod.rs index 53cf154..011845e 100644 --- a/src/mailbox/mod.rs +++ b/src/mailbox/mod.rs @@ -33,23 +33,22 @@ impl FromStr for Mailbox { if let Some((username, mut host)) = s.split_once('@') { if username.is_empty() { Err(Error::EmptyUser) - } else if username.contains(|c: char| c.is_whitespace()) { + } else if username.contains(char::is_whitespace) { Err(Error::IllegalWhitespace) } else { let username = username.to_string(); - if let Some((h, b)) = host.split_once(|c: char| c.is_whitespace()) { + if let Some((h, b)) = host.split_once(char::is_whitespace) { if h.is_empty() { return Err(Error::EmptyHost); - } else if h.contains(|c: char| c.is_whitespace()) { + } else if h.contains(char::is_whitespace) { return Err(Error::IllegalWhitespace); - } else { - host = h; - if !b.is_empty() { - if b.contains("\n") { - return Err(Error::IllegalWhitespace); - } - blurb = Some(b.to_string()); + } + host = h; + if !b.is_empty() { + if b.contains('\n') { + return Err(Error::IllegalWhitespace); } + blurb = Some(b.to_string()); } } let host = host.parse()?; diff --git a/src/mailstore/filesystem.rs b/src/mailstore/filesystem.rs index d582804..8cb1ea7 100644 --- a/src/mailstore/filesystem.rs +++ b/src/mailstore/filesystem.rs @@ -4,7 +4,6 @@ use std::{ io::{self, Write}, os::unix::fs::DirBuilderExt, path::PathBuf, - process::id, }; pub trait MultiDomain: MailStore { @@ -39,7 +38,7 @@ impl MailStore for Filesystem { fn has_mailuser(&self, mailuser: &str) -> bool { if let Some((user, host)) = mailuser.rsplit_once('@') { let mut path = self.path.clone(); - if host.contains('.') && !host.contains(|c: char| c.is_whitespace()) { + if host.contains('.') && !host.contains(char::is_whitespace) { path.push(host); path.push(user); return path.exists(); @@ -63,7 +62,7 @@ impl MailStore for Filesystem { name: folder.to_string(), messages: HashMap::new(), }; - dir.filter(|x| x.is_ok()).map(|x| x.unwrap()).for_each(|e| { + dir.filter_map(Result::ok).for_each(|e| { if let Ok(contents) = fs::read_to_string(e.path()) { if let Ok(message) = contents.parse::() { folder.messages.insert(message.id.clone(), message); @@ -77,7 +76,7 @@ impl MailStore for Filesystem { self.get_folder(user, folder).and_then(|f| { f.messages .values() - .find(|m| m.title.as_ref().map(|x| x.as_str()) == Some(title)) + .find(|m| m.title.as_ref().map(String::as_str) == Some(title)) .cloned() }) } @@ -172,7 +171,7 @@ impl MultiDomain for Filesystem { if !path.exists() { fs::DirBuilder::new() .recursive(true) - .mode(700) + .mode(0o700) .create(path)?; } Ok(()) diff --git a/src/mailstore/mod.rs b/src/mailstore/mod.rs index a55f388..eafe519 100644 --- a/src/mailstore/mod.rs +++ b/src/mailstore/mod.rs @@ -1,6 +1,6 @@ #![allow(unused_variables)] -use crate::prelude::{Host, Mailbox, Mailuser, Message, ParseMailboxError}; -use std::{collections::HashMap, convert::Infallible, io, str::FromStr}; +use crate::prelude::{Host, Mailbox, Mailuser, Message}; +use std::{collections::HashMap, io, str::FromStr}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -88,8 +88,7 @@ impl MailStore for Domain { fn has_mailuser(&self, mailuser: &str) -> bool { self.users() .iter() - .find(|x| x.username == mailuser) - .is_some() + .any(|x| x.username == mailuser) } fn get_folder(&self, user: &str, folder: &str) -> Option { @@ -106,7 +105,7 @@ impl MailStore for Domain { u.folders.get(folder).and_then(|f| { f.messages .values() - .find(|m| m.title.as_ref().map(|x| x.as_str()) == Some(title)) + .find(|m| m.title.as_ref().map(String::as_str) == Some(title)) }) }) .cloned() @@ -126,7 +125,7 @@ impl MailStore for Domain { if self.users.contains_key(user) { return Ok(()); } - let mbox = Mailbox::from_str(&format!("{user}@{}", self.host.to_string())) + let mbox = Mailbox::from_str(&format!("{user}@{}", self.host)) .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e}")))?; let folders = HashMap::new(); let acct = Account { diff --git a/src/message/mod.rs b/src/message/mod.rs index 914a018..686da98 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -68,12 +68,12 @@ impl fmt::Display for Message { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.senders.is_empty() { write!(f, "< ")?; - self.senders.iter().try_for_each(|s| write!(f, "{s}\n"))?; + self.senders.iter().try_for_each(|s| writeln!(f, "{s}"))?; } if !self.recipients.is_empty() { write!(f, ": ")?; self.recipients.iter().try_for_each(|r| write!(f, " {r}"))?; - write!(f, "\n")?; + writeln!(f)?; } write!(f, "{}\r\n", self.body) } diff --git a/src/request/mod.rs b/src/request/mod.rs index febf1ec..5881ee0 100644 --- a/src/request/mod.rs +++ b/src/request/mod.rs @@ -49,8 +49,8 @@ impl Request { pub fn recipients(&self) -> Vec { let mut recipients = vec![]; self.message.lines().for_each(|l| { - if l.starts_with(':') { - l[1..].trim().split_whitespace().for_each(|u| { + if let Some(s) = l.strip_prefix(':') { + s.split_whitespace().for_each(|u| { if let Ok(user) = u.parse() { recipients.push(user); } @@ -63,8 +63,8 @@ impl Request { pub fn senders(&self) -> Vec { let mut senders = vec![]; self.message.lines().for_each(|l| { - if l.starts_with('<') { - if let Ok(mbox) = l[1..].trim().parse() { + if let Some(s) = l.strip_prefix('<') { + if let Ok(mbox) = s.trim().parse() { senders.push(mbox); } } @@ -73,13 +73,12 @@ impl Request { } pub fn timestamp(&self) -> Option { - let mut ts = None; - self.message.lines().for_each(|l| { - if l.starts_with('@') { - ts = Some(l[1..].trim().to_string()); + for l in self.message.lines() { + if let Some(s) = l.strip_prefix('@') { + return Some(s.trim().to_string()); } - }); - ts + } + None } } diff --git a/src/sender/verifier.rs b/src/sender/verifier.rs index 663ed1f..e8ab43e 100644 --- a/src/sender/verifier.rs +++ b/src/sender/verifier.rs @@ -9,15 +9,15 @@ use { #[derive(Debug)] /// A verifier is used to verify certificates sent by the receiving server -/// during the tls handshake. For convenience the [CertificateStore] trait -/// is implemented for [std::collections::HashMap] and -/// [std::collections::BTreeMap], so a Verifier can easily +/// during the tls handshake. For convenience the [`CertificateStore`] trait +/// is implemented for [`std::collections::HashMap`] and +/// [`std::collections::BTreeMap`], so a Verifier can easily /// be constructed from those types. /// -/// This type is passed to [rustls::client::DangerousClientConfig::set_certificate_verifier] +/// This type is passed to [`rustls::client::DangerousClientConfig::set_certificate_verifier`] /// in order to allow Tofu certificate validation. /// # Examples -/// Create a Verifier from a HashMap +/// Create a Verifier from a `HashMap` /// ``` /// use std::collections::HashMap; /// use dory::prelude::{CertificateStore, Verifier}; @@ -70,7 +70,7 @@ impl ServerCertVerifier for Verifier { .borrow_mut() .insert_certificate(&name, &fp.fingerprint); } - return Ok(ServerCertVerified::assertion()); + Ok(ServerCertVerified::assertion()) } } }