Miscellaneous cleanups
This commit is contained in:
parent
5c82b53a28
commit
c905e20b36
8 changed files with 73 additions and 80 deletions
|
@ -18,15 +18,18 @@ impl<S: FingerPrintStore> Default for Builder<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: FingerPrintStore + 'static> Builder<S> {
|
impl<S: FingerPrintStore + 'static> Builder<S> {
|
||||||
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn stream(mut self, stream: TcpStream) -> Self {
|
pub fn stream(mut self, stream: TcpStream) -> Self {
|
||||||
self.stream = Some(stream);
|
self.stream = Some(stream);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn verifier(mut self, verifier: Verifier<S>) -> Self {
|
pub fn verifier(mut self, verifier: Verifier<S>) -> Self {
|
||||||
self.verifier = Some(verifier);
|
self.verifier = Some(verifier);
|
||||||
self
|
self
|
||||||
|
|
|
@ -7,8 +7,9 @@ pub struct PreBlk<'a> {
|
||||||
lines: Vec<&'a str>,
|
lines: Vec<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
enum State<'a> {
|
enum State<'a> {
|
||||||
|
#[default]
|
||||||
Normal,
|
Normal,
|
||||||
Preformatted(PreBlk<'a>),
|
Preformatted(PreBlk<'a>),
|
||||||
Quote(Vec<&'a str>),
|
Quote(Vec<&'a str>),
|
||||||
|
@ -42,8 +43,8 @@ impl fmt::Display for GemtextNode {
|
||||||
Self::ListItem(l) => writeln!(f, "* {l}"),
|
Self::ListItem(l) => writeln!(f, "* {l}"),
|
||||||
Self::Quote(q) => writeln!(f, "> {q}"),
|
Self::Quote(q) => writeln!(f, "> {q}"),
|
||||||
Self::Preformatted(a, p) => match a {
|
Self::Preformatted(a, p) => match a {
|
||||||
None => writeln!(f, "```\n{}\n```", p),
|
None => writeln!(f, "```\n{p}\n```"),
|
||||||
Some(alt) => writeln!(f, "```{alt}\n{}\n```", p),
|
Some(alt) => writeln!(f, "```{alt}\n{p}\n```"),
|
||||||
},
|
},
|
||||||
Self::Link(l) => writeln!(f, "=> {l}"),
|
Self::Link(l) => writeln!(f, "=> {l}"),
|
||||||
}
|
}
|
||||||
|
@ -107,7 +108,7 @@ impl<'a> GemtextNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_timestamp(text: &'a str) -> Self {
|
fn parse_timestamp(text: &'a str) -> Self {
|
||||||
let Some(line) = text.strip_prefix('@').map(|x| x.trim()) else {
|
let Some(line) = text.strip_prefix('@').map(str::trim) else {
|
||||||
return Self::Text(text.to_string());
|
return Self::Text(text.to_string());
|
||||||
};
|
};
|
||||||
if let Ok(dt) = line.parse() {
|
if let Ok(dt) = line.parse() {
|
||||||
|
@ -118,7 +119,7 @@ impl<'a> GemtextNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
state: State<'a>,
|
state: State<'a>,
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
|
@ -127,11 +128,7 @@ pub struct Parser<'a> {
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
state: State::Normal,
|
|
||||||
title: None,
|
|
||||||
lines: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(mut self, raw: &'a str) -> Vec<GemtextNode> {
|
pub fn parse(mut self, raw: &'a str) -> Vec<GemtextNode> {
|
||||||
|
@ -146,7 +143,7 @@ impl<'a> Parser<'a> {
|
||||||
State::Normal => {}
|
State::Normal => {}
|
||||||
State::Preformatted(_) => self.leave_preformatted(),
|
State::Preformatted(_) => self.leave_preformatted(),
|
||||||
State::Quote(q) => {
|
State::Quote(q) => {
|
||||||
let quote = q.join("\n").to_string();
|
let quote = q.join("\n");
|
||||||
self.lines.push(GemtextNode::Quote(quote));
|
self.lines.push(GemtextNode::Quote(quote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,9 +157,8 @@ impl<'a> Parser<'a> {
|
||||||
fn heading(&mut self, line: &'a str) {
|
fn heading(&mut self, line: &'a str) {
|
||||||
let line = GemtextNode::parse_heading(line);
|
let line = GemtextNode::parse_heading(line);
|
||||||
if self.title.is_none() {
|
if self.title.is_none() {
|
||||||
match &line {
|
if let GemtextNode::Heading1(t) = &line {
|
||||||
GemtextNode::Heading1(t) => self.title = Some(t.clone()),
|
self.title = Some(t.clone());
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lines.push(line);
|
self.lines.push(line);
|
||||||
|
@ -182,7 +178,7 @@ impl<'a> Parser<'a> {
|
||||||
fn leave_quote(&mut self, line: &'a str) {
|
fn leave_quote(&mut self, line: &'a str) {
|
||||||
match &mut self.state {
|
match &mut self.state {
|
||||||
State::Quote(q) => {
|
State::Quote(q) => {
|
||||||
let quote = q.join("\n").to_string();
|
let quote = q.join("\n");
|
||||||
self.lines.push(GemtextNode::Quote(quote));
|
self.lines.push(GemtextNode::Quote(quote));
|
||||||
}
|
}
|
||||||
_ => panic!("Attempt to parse as quote when not in quote mode"),
|
_ => panic!("Attempt to parse as quote when not in quote mode"),
|
||||||
|
@ -204,7 +200,7 @@ impl<'a> Parser<'a> {
|
||||||
fn leave_preformatted(&mut self) {
|
fn leave_preformatted(&mut self) {
|
||||||
match &self.state {
|
match &self.state {
|
||||||
State::Preformatted(v) => {
|
State::Preformatted(v) => {
|
||||||
let s = v.lines.join("\n").to_string();
|
let s = v.lines.join("\n");
|
||||||
self.lines
|
self.lines
|
||||||
.push(GemtextNode::Preformatted(v.alt.map(str::to_string), s));
|
.push(GemtextNode::Preformatted(v.alt.map(str::to_string), s));
|
||||||
self.state = State::Normal;
|
self.state = State::Normal;
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl MailStore for Filesystem {
|
||||||
self.get_folder(user, folder).and_then(|f| {
|
self.get_folder(user, folder).and_then(|f| {
|
||||||
f.messages
|
f.messages
|
||||||
.values()
|
.values()
|
||||||
.find(|m| m.title.as_ref().map(String::as_str) == Some(title))
|
.find(|m| m.title.as_deref() == Some(title))
|
||||||
.cloned()
|
.cloned()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl MailStore for Domain {
|
||||||
u.folders.get(folder).and_then(|f| {
|
u.folders.get(folder).and_then(|f| {
|
||||||
f.messages
|
f.messages
|
||||||
.values()
|
.values()
|
||||||
.find(|m| m.title.as_ref().map(String::as_str) == Some(title))
|
.find(|m| m.title.as_deref() == Some(title))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
|
|
|
@ -16,30 +16,28 @@ pub struct Parser {
|
||||||
|
|
||||||
impl Parser {
|
impl Parser {
|
||||||
pub fn new(id: &str) -> Self {
|
pub fn new(id: &str) -> Self {
|
||||||
let mut p = Self::default();
|
Self { id: id.to_string(), ..Default::default() }
|
||||||
p.id = id.to_string();
|
|
||||||
p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(mut self, content: &str) -> Result<Message, super::Error> {
|
pub fn parse(mut self, content: &str) -> Result<Message, super::Error> {
|
||||||
let lines = content.lines();
|
let lines = content.lines();
|
||||||
for l in lines {
|
for l in lines {
|
||||||
match l {
|
match l {
|
||||||
s if s.starts_with("<") && self.from.is_none() && self.body.is_empty() => {
|
s if s.starts_with('<') && self.from.is_none() && self.body.is_empty() => {
|
||||||
let s = s.strip_prefix('<').unwrap().trim();
|
let s = s.strip_prefix('<').unwrap().trim();
|
||||||
let from: Mailbox = s.parse()?;
|
let from: Mailbox = s.parse()?;
|
||||||
self.from = Some(from);
|
self.from = Some(from);
|
||||||
}
|
}
|
||||||
s if s.starts_with("<") && self.body.is_empty() => {
|
s if s.starts_with('<') && self.body.is_empty() => {
|
||||||
let sndr = s.strip_prefix('<').unwrap().trim();
|
let sndr = s.strip_prefix('<').unwrap().trim();
|
||||||
let from: Mailbox = sndr.parse()?;
|
let from: Mailbox = sndr.parse()?;
|
||||||
self.senders.push(from);
|
self.senders.push(from);
|
||||||
}
|
}
|
||||||
s if s.starts_with(":") && self.body.is_empty() => {
|
s if s.starts_with(':') && self.body.is_empty() => {
|
||||||
self.recipients = s.parse()?;
|
self.recipients = s.parse()?;
|
||||||
}
|
}
|
||||||
s if s.starts_with("@") && self.timestamp.is_none() && self.body.is_empty() => {
|
s if s.starts_with('@') && self.timestamp.is_none() && self.body.is_empty() => {
|
||||||
self.timestamp = Some(s.strip_prefix("@").unwrap().trim().to_string());
|
self.timestamp = Some(s.strip_prefix('@').unwrap().trim().to_string());
|
||||||
}
|
}
|
||||||
s if s.starts_with("###") && self.title.is_none() => {
|
s if s.starts_with("###") && self.title.is_none() => {
|
||||||
if let Some(t) = s.strip_prefix("###").map(|x| x.trim().to_string()) {
|
if let Some(t) = s.strip_prefix("###").map(|x| x.trim().to_string()) {
|
||||||
|
@ -59,8 +57,8 @@ impl Parser {
|
||||||
}
|
}
|
||||||
self.body.push_str(s);
|
self.body.push_str(s);
|
||||||
}
|
}
|
||||||
s if s.starts_with("#") && self.title.is_none() => {
|
s if s.starts_with('#') && self.title.is_none() => {
|
||||||
if let Some(t) = s.strip_prefix("#").map(|x| x.trim().to_string()) {
|
if let Some(t) = s.strip_prefix('#').map(|x| x.trim().to_string()) {
|
||||||
self.title = Some(t);
|
self.title = Some(t);
|
||||||
}
|
}
|
||||||
if !self.body.is_empty() {
|
if !self.body.is_empty() {
|
||||||
|
|
|
@ -14,5 +14,5 @@ pub use super::{
|
||||||
AuthenticationFailure, Error as ParseStatusError, PermanentFailure, Redirect, Status,
|
AuthenticationFailure, Error as ParseStatusError, PermanentFailure, Redirect, Status,
|
||||||
TemporaryFailure,
|
TemporaryFailure,
|
||||||
},
|
},
|
||||||
time::{Error as ParseTimeError, DateTime, TimeZone, Sign, Parser as TimeParser},
|
time::{DateTime, Error as ParseTimeError, Parser as TimeParser, Sign, TimeZone},
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,35 +132,33 @@ impl DateTime {
|
||||||
pub fn normalize(&self) -> Option<Self> {
|
pub fn normalize(&self) -> Option<Self> {
|
||||||
if self.tz == Some(TimeZone::UTC) {
|
if self.tz == Some(TimeZone::UTC) {
|
||||||
Some(*self)
|
Some(*self)
|
||||||
} else {
|
} else if let Some(TimeZone::Offset(tz)) = self.tz {
|
||||||
if let Some(TimeZone::Offset(tz)) = self.tz {
|
let hour = if let Some(hour) = self.hour {
|
||||||
let hour = if let Some(hour) = self.hour {
|
match tz.sign {
|
||||||
match tz.sign {
|
Sign::Positive => Some(hour + tz.hours),
|
||||||
Sign::Positive => Some(hour + tz.hours),
|
Sign::Negative => Some(hour - tz.hours),
|
||||||
Sign::Negative => Some(hour - tz.hours),
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let minute = 'blk: {
|
|
||||||
if let Some(minutes) = self.minute {
|
|
||||||
if let Some(o) = tz.minutes {
|
|
||||||
match tz.sign {
|
|
||||||
Sign::Positive => break 'blk Some(minutes + o),
|
|
||||||
Sign::Negative => break 'blk Some(minutes - o),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Some(DateTime {
|
|
||||||
hour,
|
|
||||||
minute,
|
|
||||||
..*self
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
};
|
||||||
|
let minute = 'blk: {
|
||||||
|
if let Some(minutes) = self.minute {
|
||||||
|
if let Some(o) = tz.minutes {
|
||||||
|
match tz.sign {
|
||||||
|
Sign::Positive => break 'blk Some(minutes + o),
|
||||||
|
Sign::Negative => break 'blk Some(minutes - o),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Some(DateTime {
|
||||||
|
hour,
|
||||||
|
minute,
|
||||||
|
..*self
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ impl<'a> Parser<'a> {
|
||||||
let max = match self.month {
|
let max = match self.month {
|
||||||
Some(1 | 3 | 5 | 7 | 10 | 12) => 31,
|
Some(1 | 3 | 5 | 7 | 10 | 12) => 31,
|
||||||
Some(2) => {
|
Some(2) => {
|
||||||
if self.year.unwrap() % 4 == 0 {
|
let year = self.year.unwrap();
|
||||||
|
if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) {
|
||||||
29
|
29
|
||||||
} else {
|
} else {
|
||||||
28
|
28
|
||||||
|
@ -175,10 +176,9 @@ impl<'a> Parser<'a> {
|
||||||
Mode::Month => {
|
Mode::Month => {
|
||||||
if self.month.is_some() {
|
if self.month.is_some() {
|
||||||
return Err(Error::UnexpectedChar(self.mode, '-'));
|
return Err(Error::UnexpectedChar(self.mode, '-'));
|
||||||
} else {
|
|
||||||
self.format = Format::Extended;
|
|
||||||
self.sep = true;
|
|
||||||
}
|
}
|
||||||
|
self.format = Format::Extended;
|
||||||
|
self.sep = true;
|
||||||
}
|
}
|
||||||
Mode::Day => {
|
Mode::Day => {
|
||||||
if self.day.is_some() || self.format == Format::Basic {
|
if self.day.is_some() || self.format == Format::Basic {
|
||||||
|
@ -188,11 +188,11 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mode::Hour | Mode::Minute | Mode::Second => {
|
Mode::Hour | Mode::Minute | Mode::Second => {
|
||||||
if !self.buffer.is_empty() {
|
if self.buffer.is_empty() {
|
||||||
return Err(Error::UnexpectedChar(self.mode, '-'));
|
|
||||||
} else {
|
|
||||||
self.buffer.push('-');
|
self.buffer.push('-');
|
||||||
self.mode = Mode::TimeZone;
|
self.mode = Mode::TimeZone;
|
||||||
|
} else {
|
||||||
|
return Err(Error::UnexpectedChar(self.mode, '-'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mode::TimeZone => {
|
Mode::TimeZone => {
|
||||||
|
@ -215,16 +215,14 @@ impl<'a> Parser<'a> {
|
||||||
Mode::Hour | Mode::Minute | Mode::Second => {
|
Mode::Hour | Mode::Minute | Mode::Second => {
|
||||||
if !self.buffer.is_empty() || self.format == Format::Basic {
|
if !self.buffer.is_empty() || self.format == Format::Basic {
|
||||||
return Err(Error::UnexpectedChar(self.mode, ':'));
|
return Err(Error::UnexpectedChar(self.mode, ':'));
|
||||||
} else {
|
|
||||||
self.sep = true;
|
|
||||||
}
|
}
|
||||||
|
self.sep = true;
|
||||||
}
|
}
|
||||||
Mode::TimeZone => {
|
Mode::TimeZone => {
|
||||||
if !self.buffer.len() == 2 || self.format == Format::Basic {
|
if !self.buffer.len() == 2 || self.format == Format::Basic {
|
||||||
return Err(Error::UnexpectedChar(self.mode, ':'));
|
return Err(Error::UnexpectedChar(self.mode, ':'));
|
||||||
} else {
|
|
||||||
self.sep = true;
|
|
||||||
}
|
}
|
||||||
|
self.sep = true;
|
||||||
}
|
}
|
||||||
Mode::Finish => return Err(Error::TrailingGarbage),
|
Mode::Finish => return Err(Error::TrailingGarbage),
|
||||||
}
|
}
|
||||||
|
@ -233,11 +231,10 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn tee(&mut self) -> Result<(), Error> {
|
fn tee(&mut self) -> Result<(), Error> {
|
||||||
if self.mode != Mode::Hour || !self.buffer.is_empty() {
|
if self.mode != Mode::Hour || !self.buffer.is_empty() {
|
||||||
Err(Error::UnexpectedChar(self.mode, 'T'))
|
return Err(Error::UnexpectedChar(self.mode, 'T'));
|
||||||
} else {
|
|
||||||
self.sep = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
self.sep = true;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zed(&mut self) -> Result<(), Error> {
|
fn zed(&mut self) -> Result<(), Error> {
|
||||||
|
@ -247,21 +244,22 @@ impl<'a> Parser<'a> {
|
||||||
|| !self.buffer.is_empty()
|
|| !self.buffer.is_empty()
|
||||||
{
|
{
|
||||||
return Err(Error::UnexpectedChar(self.mode, 'Z'));
|
return Err(Error::UnexpectedChar(self.mode, 'Z'));
|
||||||
} else {
|
|
||||||
self.tz = Some(TimeZone::UTC);
|
|
||||||
self.mode = Mode::Finish;
|
|
||||||
}
|
}
|
||||||
|
self.tz = Some(TimeZone::UTC);
|
||||||
|
self.mode = Mode::Finish;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plus(&mut self) -> Result<(), Error> {
|
fn plus(&mut self) -> Result<(), Error> {
|
||||||
if self.mode != Mode::TimeZone && self.mode != Mode::Finish || !self.buffer.is_empty() {
|
if self.mode != Mode::TimeZone && self.mode != Mode::Finish
|
||||||
|
|| !self.buffer.is_empty()
|
||||||
|
|| self.mode == Mode::Year
|
||||||
|
|| self.mode == Mode::Month
|
||||||
|
|| self.mode == Mode::Day
|
||||||
|
{
|
||||||
return Err(Error::UnexpectedChar(self.mode, '+'));
|
return Err(Error::UnexpectedChar(self.mode, '+'));
|
||||||
} else if self.mode == Mode::Year || self.mode == Mode::Month || self.mode == Mode::Day {
|
|
||||||
return Err(Error::UnexpectedChar(self.mode, '+'));
|
|
||||||
} else {
|
|
||||||
self.buffer.push('+');
|
|
||||||
}
|
}
|
||||||
|
self.buffer.push('+');
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +287,7 @@ impl<'a> Parser<'a> {
|
||||||
sign,
|
sign,
|
||||||
hours,
|
hours,
|
||||||
minutes,
|
minutes,
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Reference in a new issue