Add Mailbox
, Message
, Lines
, Recipients
types
This commit is contained in:
parent
c57bb83c5c
commit
b2f60c61ec
7 changed files with 216 additions and 0 deletions
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
digest = "0.10.7"
|
||||
sha2 = "0.10.6"
|
||||
time = "0.3.21"
|
||||
x509-parser = "0.15.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
mod certificate_store;
|
||||
mod fingerprint;
|
||||
mod host;
|
||||
mod mailbox;
|
||||
mod message;
|
||||
pub mod prelude;
|
||||
mod receiver;
|
||||
mod request;
|
||||
|
|
35
src/mailbox/error.rs
Normal file
35
src/mailbox/error.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use {crate::prelude::ParseHostError, std::fmt};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
/// Errors which can occur when parsing a request
|
||||
pub enum Error {
|
||||
MissingSeparator,
|
||||
EmptyUser,
|
||||
EmptyHost,
|
||||
ParseHostError(ParseHostError),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::ParseHostError(e) => write!(f, "{e}"),
|
||||
_ => write!(f, "{self:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::ParseHostError(e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseHostError> for Error {
|
||||
fn from(value: ParseHostError) -> Self {
|
||||
Self::ParseHostError(value)
|
||||
}
|
||||
}
|
||||
|
56
src/mailbox/mod.rs
Normal file
56
src/mailbox/mod.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use std::{fmt, str::FromStr};
|
||||
use crate::prelude::Host;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod error;
|
||||
pub use error::Error;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Mailbox {
|
||||
pub username: String,
|
||||
pub host: Host,
|
||||
pub blurb: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Mailbox {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}@{}",
|
||||
self.username,
|
||||
self.host,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Mailbox {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut blurb = None;
|
||||
if let Some((username, mut host)) = s.split_once('@') {
|
||||
if username.is_empty() {
|
||||
Err(Error::EmptyUser)
|
||||
} else {
|
||||
let username = username.to_string();
|
||||
if let Some((h, b)) = host.split_once(|c: char| c.is_whitespace()) {
|
||||
if h.is_empty() {
|
||||
return Err(Error::EmptyHost);
|
||||
} else {
|
||||
host = h;
|
||||
if !b.is_empty() {
|
||||
blurb = Some(b.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
let host = host.parse()?;
|
||||
Ok(Self { username, host, blurb })
|
||||
}
|
||||
} else {
|
||||
Err(Error::MissingSeparator)
|
||||
}
|
||||
}
|
||||
}
|
36
src/message/error.rs
Normal file
36
src/message/error.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use {crate::prelude::ParseHostError, std::fmt};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
/// Errors which can occur when parsing a request
|
||||
pub enum Error {
|
||||
MissingSeparator,
|
||||
EmptyUser,
|
||||
EmptyHost,
|
||||
EmptyMessage,
|
||||
ParseHostError(ParseHostError),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::ParseHostError(e) => write!(f, "{e}"),
|
||||
_ => write!(f, "{self:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::ParseHostError(e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseHostError> for Error {
|
||||
fn from(value: ParseHostError) -> Self {
|
||||
Self::ParseHostError(value)
|
||||
}
|
||||
}
|
||||
|
84
src/message/mod.rs
Normal file
84
src/message/mod.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use std::{fmt, str::FromStr};
|
||||
use crate::prelude::{Host, Mailbox};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod error;
|
||||
pub use error::Error;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Recipients {
|
||||
pub boxes: Vec<Mailbox>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Recipients {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, ":")?;
|
||||
self.boxes.iter().try_for_each(|b| {
|
||||
write!(f, " {b}")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Lines {
|
||||
Sender(Mailbox),
|
||||
Recipients(Recipients),
|
||||
Timestamp(String),
|
||||
Text(String),
|
||||
Heading1(String),
|
||||
Heading2(String),
|
||||
Heading3(String),
|
||||
Quote(String),
|
||||
Preformatted(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Lines {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Sender(m) => writeln!(f, "< {m}"),
|
||||
Self::Recipients(r) => writeln!(f, "{r}"),
|
||||
Self::Timestamp(t) => writeln!(f, "@ {t}"),
|
||||
Self::Text(t) => writeln!(f, "{t}"),
|
||||
Self::Heading1(h) => writeln!(f, "# {h}"),
|
||||
Self::Heading2(h) => writeln!(f, "## {h}"),
|
||||
Self::Heading3(h) => writeln!(f, "### {h}"),
|
||||
Self::Quote(q) => {
|
||||
for l in q.lines() {
|
||||
writeln!(f, "> {l}")?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Message {
|
||||
pub senders: Vec<Mailbox>,
|
||||
pub recipients: Vec<Mailbox>,
|
||||
pub timstamp: Option<String>,
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
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")
|
||||
})?;
|
||||
}
|
||||
if !self.recipients.is_empty() {
|
||||
write!(f, ": ")?;
|
||||
self.recipients.iter().try_for_each(|r| {
|
||||
write!(f, " {r}")
|
||||
})?;
|
||||
write!(f, "\n")?;
|
||||
}
|
||||
write!(f, "{}\r\n", self.body)
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ pub use super::{
|
|||
certificate_store::CertificateStore,
|
||||
fingerprint::{Error as FingerprintError, Fingerprint, GetFingerprint},
|
||||
host::{Error as ParseHostError, Host},
|
||||
mailbox::{Error as ParseMailboxError, Mailbox},
|
||||
message::{Error as ParseMessageError, Lines, Message, Recipients},
|
||||
//receiver,
|
||||
request::{Error as ParseRequestError, Request},
|
||||
response::{Error as ParseResponseError, Response},
|
||||
|
|
Loading…
Add table
Reference in a new issue