From 805e5cdd14c3fac52bb59b24fbafb7cc6ea46829 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Thu, 1 Jun 2023 23:34:36 -0400 Subject: [PATCH] Some work towards the gemtext parser --- src/connection/builder.rs | 5 +- src/connection/mod.rs | 3 +- src/mailstore/mod.rs | 4 +- src/message/link.rs | 10 ++- src/message/mod.rs | 31 --------- src/message/parser.rs | 128 +++++++++++++++++++++++++++++++++++++- 6 files changed, 141 insertions(+), 40 deletions(-) diff --git a/src/connection/builder.rs b/src/connection/builder.rs index 84170f6..c51430f 100644 --- a/src/connection/builder.rs +++ b/src/connection/builder.rs @@ -10,7 +10,10 @@ pub struct Builder { impl Default for Builder { fn default() -> Self { - Self { stream: None, verifier: None } + Self { + stream: None, + verifier: None, + } } } diff --git a/src/connection/mod.rs b/src/connection/mod.rs index 7b6fecc..ef4b905 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -7,5 +7,4 @@ pub struct Connection { pub inner: rustls::ServerConnection, } -impl Connection { -} +impl Connection {} diff --git a/src/mailstore/mod.rs b/src/mailstore/mod.rs index eafe519..976217f 100644 --- a/src/mailstore/mod.rs +++ b/src/mailstore/mod.rs @@ -86,9 +86,7 @@ impl MailStore for Domain { } fn has_mailuser(&self, mailuser: &str) -> bool { - self.users() - .iter() - .any(|x| x.username == mailuser) + self.users().iter().any(|x| x.username == mailuser) } fn get_folder(&self, user: &str, folder: &str) -> Option { diff --git a/src/message/link.rs b/src/message/link.rs index 2ee0e92..10df54f 100644 --- a/src/message/link.rs +++ b/src/message/link.rs @@ -27,9 +27,15 @@ impl FromStr for Link { 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()) }) + Ok(Self { + url: url.to_string(), + display: Some(display.to_string()), + }) } else { - Ok(Self { url: s.to_string(), display: None }) + Ok(Self { + url: s.to_string(), + display: None, + }) } } } diff --git a/src/message/mod.rs b/src/message/mod.rs index 35554ec..327b5f8 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -21,37 +21,6 @@ impl fmt::Display for Recipients { } } -#[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), - Link(Link), -} - -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) => writeln!(f, "> {q}"), - Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"), - Self::Link(l) => writeln!(f, "=> {l}"), - } - } -} - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct Message { diff --git a/src/message/parser.rs b/src/message/parser.rs index 50868b4..b848b6e 100644 --- a/src/message/parser.rs +++ b/src/message/parser.rs @@ -1,2 +1,128 @@ +use std::fmt; +use crate::prelude::Mailbox; +use super::{Link, Recipients}; + #[derive(Debug)] -pub struct Parser; +pub struct PreBlk<'a> { + alt: Option<&'a str>, + lines: Vec<&'a str>, +} + +#[derive(Debug)] +enum State<'a> { + Normal, + Preformatted(PreBlk<'a>), + Quote(Vec<&'a str>), +} + +#[derive(Clone, Debug, PartialEq)] +pub enum GemtextNode { + Sender(Mailbox), + Recipients(Recipients), + Timestamp(String), + Text(String), + Heading1(String), + Heading2(String), + Heading3(String), + Quote(String), + Preformatted(String), + Link(Link), +} + +impl fmt::Display for GemtextNode { + 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) => writeln!(f, "> {q}"), + Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"), + Self::Link(l) => writeln!(f, "=> {l}"), + } + } +} + +impl<'a> GemtextNode { + fn parse_link(text: &'a str) -> Self { + todo!() + } + + fn parse_prompt(text: &'a str) -> Self { + todo!() + } + + fn parse_heading(text: &'a str) -> Self { + todo!() + } + + fn parse_list_item(text: &'a str) -> Self { + todo!() + } + + fn parse_blockquote(text: &'a str) -> Self { + todo!() + } + + fn parse_senders(text: &'a str) -> Self { + todo!() + } + + fn parse_recipients(text: &'a str) -> Self { + todo!() + } + + fn parse_timestamp(text: &'a str) -> Self { + todo!() + } +} + +#[derive(Debug)] +pub struct Parser<'a> { + state: State<'a>, + lines: Vec, +} + +impl<'a> Parser<'a> { + pub fn new() -> Self { + Self { + state: State::Normal, + lines: vec![] + } + } + + fn parse(mut self, raw: &'a str) -> Vec { + for line in raw.lines() { + match self.state { + State::Normal => self.parse_normal(line), + State::Preformatted(_) => self.parse_preformatted(line), + State::Quote(_) => self.parse_quote(line), + } + } + self.lines + } + + fn parse_normal(&mut self, line: &'a str) { + match line { + s if s.starts_with("=>") => {}, + s if s.starts_with('#') => {}, + s if s.starts_with('*') => {}, + s if s.starts_with('>') => {}, + s if s.starts_with("```") => {}, + s if s.starts_with('<') => {}, + s if s.starts_with(':') => {}, + s if s.starts_with('@') => {}, + s => {}, + } + } + + fn parse_preformatted(&mut self, line: &'a str) { + } + + fn parse_quote(&mut self, line: &'a str) { + } +} +