Progress on the Gemtext parser
This commit is contained in:
parent
60a8e74af3
commit
200dd8b451
3 changed files with 64 additions and 17 deletions
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||
mod error;
|
||||
mod link;
|
||||
mod parser;
|
||||
pub use {error::Error, link::Link, parser::Parser};
|
||||
pub use {error::Error, link::Link, parser::{GemtextNode, Parser}};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Recipients {
|
||||
|
|
|
@ -17,13 +17,14 @@ enum State<'a> {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GemtextNode {
|
||||
Sender(Mailbox),
|
||||
Sender(Vec<Mailbox>),
|
||||
Recipients(Recipients),
|
||||
Timestamp(String),
|
||||
Text(String),
|
||||
Heading1(String),
|
||||
Heading2(String),
|
||||
Heading3(String),
|
||||
ListItem(String),
|
||||
Quote(String),
|
||||
Preformatted(String),
|
||||
Link(Link),
|
||||
|
@ -32,13 +33,18 @@ pub enum GemtextNode {
|
|||
impl fmt::Display for GemtextNode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Sender(m) => writeln!(f, "< {m}"),
|
||||
Self::Sender(m) => {
|
||||
write!(f, "<")?;
|
||||
m.iter().try_for_each(|m| write!(f, " {m}"))?;
|
||||
writeln!(f)
|
||||
},
|
||||
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::ListItem(l) => writeln!(f, "* {l}"),
|
||||
Self::Quote(q) => writeln!(f, "> {q}"),
|
||||
Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"),
|
||||
Self::Link(l) => writeln!(f, "=> {l}"),
|
||||
|
@ -48,27 +54,56 @@ impl fmt::Display for GemtextNode {
|
|||
|
||||
impl<'a> GemtextNode {
|
||||
fn parse_link(text: &'a str) -> Self {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn parse_prompt(text: &'a str) -> Self {
|
||||
todo!()
|
||||
if let Ok(link) = text.parse() {
|
||||
Self::Link(link)
|
||||
} else {
|
||||
Self::Text(text.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_heading(text: &'a str) -> Self {
|
||||
todo!()
|
||||
if let Some((h, s)) = text.split_once(char::is_whitespace) {
|
||||
match h {
|
||||
"#" => Self::Heading1(s.to_string()),
|
||||
"##" => Self::Heading2(s.to_string()),
|
||||
"###" => Self::Heading3(s.to_string()),
|
||||
_ => Self::Text(text.to_string()),
|
||||
}
|
||||
} else {
|
||||
Self::Text(text.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_list_item(text: &'a str) -> Self {
|
||||
todo!()
|
||||
match text.split_once(char::is_whitespace) {
|
||||
Some((pre, s)) if pre == "*" => GemtextNode::ListItem(s.to_string()),
|
||||
_ => GemtextNode::Text(text.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_blockquote(text: &'a str) -> Self {
|
||||
todo!()
|
||||
match text.split_once(char::is_whitespace) {
|
||||
Some((prefix, suffix)) if prefix == ">" => GemtextNode::Quote(suffix.to_string()),
|
||||
_ => GemtextNode::Text(text.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_senders(text: &'a str) -> Self {
|
||||
todo!()
|
||||
let mut split = text.split_whitespace();
|
||||
match split.next() {
|
||||
Some(s) if s == "<" => {
|
||||
let mut senders: Vec<Mailbox> = vec![];
|
||||
for s in split {
|
||||
if let Ok(m) = s.parse() {
|
||||
senders.push(m);
|
||||
} else {
|
||||
return Self::Text(text.to_string());
|
||||
}
|
||||
}
|
||||
Self::Sender(senders)
|
||||
}
|
||||
_ => Self::Text(text.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_recipients(text: &'a str) -> Self {
|
||||
|
@ -94,7 +129,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse(mut self, raw: &'a str) -> Vec<GemtextNode> {
|
||||
pub fn parse(mut self, raw: &'a str) -> Vec<GemtextNode> {
|
||||
for line in raw.lines() {
|
||||
match self.state {
|
||||
State::Normal => self.parse_normal(line),
|
||||
|
@ -105,11 +140,23 @@ impl<'a> Parser<'a> {
|
|||
self.lines
|
||||
}
|
||||
|
||||
fn link(&mut self, line: &'a str) {
|
||||
self.lines.push(GemtextNode::parse_link(line));
|
||||
}
|
||||
|
||||
fn heading(&mut self, line: &'a str) {
|
||||
self.lines.push(GemtextNode::parse_heading(line));
|
||||
}
|
||||
|
||||
fn list_item(&mut self, line: &'a str) {
|
||||
self.lines.push(GemtextNode::parse_list_item(line));
|
||||
}
|
||||
|
||||
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("=>") => self.link(s),
|
||||
s if s.starts_with('#') => self.heading(s),
|
||||
s if s.starts_with('*') => self.list_item(s),
|
||||
s if s.starts_with('>') => {},
|
||||
s if s.starts_with("```") => {},
|
||||
s if s.starts_with('<') => {},
|
||||
|
|
|
@ -4,7 +4,7 @@ pub use super::{
|
|||
host::{Error as ParseHostError, Host},
|
||||
mailbox::{Error as ParseMailboxError, Mailbox},
|
||||
mailuser::Mailuser,
|
||||
message::{Error as ParseMessageError, Lines, Message, Recipients},
|
||||
message::{Error as ParseMessageError, GemtextNode, Message, Recipients},
|
||||
//receiver,
|
||||
request::{Error as ParseRequestError, Request},
|
||||
response::{Error as ParseResponseError, Response},
|
||||
|
|
Loading…
Add table
Reference in a new issue