diff --git a/src/connection/mod.rs b/src/connection/mod.rs index c420bff..7b6fecc 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -6,3 +6,6 @@ pub mod verifier; pub struct Connection { pub inner: rustls::ServerConnection, } + +impl Connection { +} diff --git a/src/message/error.rs b/src/message/error.rs index 368ef53..20d4b7c 100644 --- a/src/message/error.rs +++ b/src/message/error.rs @@ -8,6 +8,7 @@ pub enum Error { EmptyHost, EmptyMessage, ParseHostError(ParseHostError), + MalformedLink, } impl fmt::Display for Error { diff --git a/src/message/link.rs b/src/message/link.rs new file mode 100644 index 0000000..1bbbf05 --- /dev/null +++ b/src/message/link.rs @@ -0,0 +1,59 @@ +use std::{fmt::Display, str::FromStr}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +pub struct Link { + pub url: T, + pub display: Option, +} + +impl Display for Link +where T: Display + PartialEq { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self.display { + Some(d) => write!(f, "=> {} {d}", self.url), + None => write!(f, "=> {}", self.url), + } + } +} + +impl FromStr for Link { + type Err = super::Error; + + fn from_str(s: &str) -> Result { + let Some(s) = s.strip_prefix("=> ") else { + return Err(super::Error::MalformedLink); + }; + if let Some((url, display)) = s.split_once(char::is_whitespace) { + Ok(Self { url: url.to_string(), display: Some(display.to_string()) }) + } else { + Ok(Self { url: s.to_string(), display: None }) + } + } +} + +impl TryFrom<&str> for Link { + type Error = super::Error; + + fn try_from(value: &str) -> Result { + value.parse() + } +} + +impl<'a> TryFrom<&'a str> for Link<&'a str> { + type Error = super::Error; + + fn try_from(value: &'a str) -> Result { + let Some(s) = value.strip_prefix("=> ") else { + return Err(super::Error::MalformedLink); + }; + if let Some((url, display)) = s.split_once(char::is_whitespace) { + Ok(Self { url, display: Some(display) }) + } else { + Ok(Self { url: s , display: None }) + } + } +} diff --git a/src/message/mod.rs b/src/message/mod.rs index 686da98..b8e39a3 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -1,11 +1,13 @@ use crate::prelude::{Host, Mailbox}; -use std::{fmt, str::FromStr}; +use std::{fmt, str::FromStr, io::BufRead}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; mod error; -pub use error::Error; +mod link; +mod parser; +pub use {error::Error, link::Link, parser::Parser}; #[derive(Clone, Debug, PartialEq)] pub struct Recipients { @@ -20,19 +22,21 @@ impl fmt::Display for Recipients { } #[derive(Clone, Debug, PartialEq)] -pub enum Lines { +pub enum Lines { Sender(Mailbox), Recipients(Recipients), - Timestamp(String), - Text(String), - Heading1(String), - Heading2(String), - Heading3(String), - Quote(String), - Preformatted(String), + Timestamp(T), + Text(T), + Heading1(T), + Heading2(T), + Heading3(T), + Quote(T), + Preformatted(T), + Link(Link), } -impl fmt::Display for Lines { +impl fmt::Display for Lines +where T: fmt::Display + PartialEq + BufRead { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Sender(m) => writeln!(f, "< {m}"), @@ -42,13 +46,9 @@ impl fmt::Display for Lines { 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::Quote(q) => writeln!(f, "> {q}"), Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"), + Self::Link(l) => writeln!(f, "=> {l}"), } } } @@ -57,6 +57,7 @@ impl fmt::Display for Lines { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct Message { pub id: String, + pub from: Mailbox, pub senders: Vec, pub recipients: Vec, pub timstamp: Option, diff --git a/src/message/parser.rs b/src/message/parser.rs index e69de29..50868b4 100644 --- a/src/message/parser.rs +++ b/src/message/parser.rs @@ -0,0 +1,2 @@ +#[derive(Debug)] +pub struct Parser;