Scaffold a second content parser pass
This commit is contained in:
parent
3b515324a2
commit
d51b9a135e
19 changed files with 282 additions and 90 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
use axum::{body::Body, extract::Path, http::Response};
|
use axum::{body::Body, extract::Path, http::Response};
|
||||||
use crate::syntax::content::elements::paragraph::Paragraph;
|
use crate::syntax::content::parsers::line::elements::paragraph::Paragraph;
|
||||||
use crate::syntax::content::parser;
|
use crate::syntax::content;
|
||||||
|
|
||||||
|
use crate::syntax::content::parsers::word::elements::literal::Literal;
|
||||||
use crate::{formats::populate_graph, handlers, types::Node};
|
use crate::{formats::populate_graph, handlers, types::Node};
|
||||||
|
|
||||||
pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
||||||
|
|
@ -16,7 +17,7 @@ pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
||||||
context.insert("incoming", &graph.incoming.get(&id));
|
context.insert("incoming", &graph.incoming.get(&id));
|
||||||
context.insert("config", &graph.meta.config);
|
context.insert("config", &graph.meta.config);
|
||||||
|
|
||||||
let out_text = parser::read::<Paragraph>(&node.text);
|
let out_text = content::parse::<Paragraph, Literal>(&node.text);
|
||||||
context.insert("text", &out_text);
|
context.insert("text", &out_text);
|
||||||
|
|
||||||
let not_found = *node == empty_node;
|
let not_found = *node == empty_node;
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,14 @@ use axum::{
|
||||||
use crate::{
|
use crate::{
|
||||||
formats::populate_graph,
|
formats::populate_graph,
|
||||||
handlers,
|
handlers,
|
||||||
syntax::content::parser,
|
syntax::content::{
|
||||||
|
self,
|
||||||
|
parsers::{
|
||||||
|
line::elements::{paragraph::Paragraph, span::Span},
|
||||||
|
word::elements::literal::Literal,
|
||||||
|
},
|
||||||
|
},
|
||||||
types::{Config, Node},
|
types::{Config, Node},
|
||||||
syntax::content::elements::{span::Span, paragraph::Paragraph},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[expect(clippy::unused_async)]
|
#[expect(clippy::unused_async)]
|
||||||
|
|
@ -24,8 +29,12 @@ pub async fn page(template: &str) -> Response<Body> {
|
||||||
context.insert("root_node", &root_node);
|
context.insert("root_node", &root_node);
|
||||||
|
|
||||||
let text_parsed_config = Config {
|
let text_parsed_config = Config {
|
||||||
footer_text: parser::read::<Span>(&graph.meta.config.footer_text),
|
footer_text: content::parse::<Span, Literal>(
|
||||||
about_text: parser::read::<Paragraph>(&graph.meta.config.about_text),
|
&graph.meta.config.footer_text,
|
||||||
|
),
|
||||||
|
about_text: content::parse::<Paragraph, Literal>(
|
||||||
|
&graph.meta.config.about_text,
|
||||||
|
),
|
||||||
..graph.meta.config
|
..graph.meta.config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
use elements::{header::Header};
|
use token::{Token};
|
||||||
use units::{Token, Lexeme};
|
use parsers::{line::Line, word::Word};
|
||||||
|
use lexeme::Lexeme;
|
||||||
|
|
||||||
mod units;
|
mod token;
|
||||||
pub mod elements;
|
pub mod lexeme;
|
||||||
pub mod parser;
|
pub mod parsers;
|
||||||
|
|
||||||
pub trait Parseable: Into<Token> {
|
pub trait Parseable: Into<Token> {
|
||||||
fn probe(lexeme: &Lexeme) -> bool;
|
fn probe(lexeme: &Lexeme) -> bool;
|
||||||
|
|
@ -13,14 +14,10 @@ pub trait Parseable: Into<Token> {
|
||||||
|
|
||||||
type Probe = fn(&Lexeme) -> bool;
|
type Probe = fn(&Lexeme) -> bool;
|
||||||
type Lexer = fn(&Lexeme) -> Token;
|
type Lexer = fn(&Lexeme) -> Token;
|
||||||
type LexEntry = (Probe, Lexer);
|
type LexMap<'lm> = &'lm [(Probe, Lexer)];
|
||||||
type LexMap<'lm> = &'lm [LexEntry];
|
|
||||||
|
|
||||||
const LEXMAP: LexMap =
|
fn make_lexmap<DefaultToken: Parseable>(base: LexMap) -> Vec<(Probe, Lexer)> {
|
||||||
&[(Header::probe, |lexeme| Token::Header(Header::lex(lexeme)))];
|
let mut vector: Vec<(Probe, Lexer)> = base.to_vec();
|
||||||
|
|
||||||
fn make_lexmap<DefaultToken: Parseable>() -> Vec<LexEntry> {
|
|
||||||
let mut vector: Vec<(Probe, Lexer)> = LEXMAP.to_vec();
|
|
||||||
|
|
||||||
fn adapter<D: Parseable>(lex: &Lexeme) -> Token {
|
fn adapter<D: Parseable>(lex: &Lexeme) -> Token {
|
||||||
D::lex(lex).into()
|
D::lex(lex).into()
|
||||||
|
|
@ -29,3 +26,12 @@ fn make_lexmap<DefaultToken: Parseable>() -> Vec<LexEntry> {
|
||||||
vector.push((DefaultToken::probe, adapter::<DefaultToken>));
|
vector.push((DefaultToken::probe, adapter::<DefaultToken>));
|
||||||
vector
|
vector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse<DefaultLineToken: Parseable, DefaultWordToken: Parseable>(
|
||||||
|
text: &str,
|
||||||
|
) -> String {
|
||||||
|
let escaped_text = tera::escape_html(text);
|
||||||
|
parsers::line::parser::read::<DefaultLineToken>(
|
||||||
|
&parsers::word::parser::read::<DefaultWordToken>(&escaped_text),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
24
src/syntax/content/lexeme.rs
Normal file
24
src/syntax/content/lexeme.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
use super::parsers::{line::Line, word::Word};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Lexeme {
|
||||||
|
Line(Line),
|
||||||
|
Word(Word),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lexeme {
|
||||||
|
pub fn to_raw(&self) -> String {
|
||||||
|
match *self {
|
||||||
|
Lexeme::Line(ref d) => d.raw.clone(),
|
||||||
|
Lexeme::Word(ref d) => d.raw.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_vec(self) -> Vec<String> {
|
||||||
|
self.to_raw().split(' ').map(str::to_string).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first(self) -> Option<String> {
|
||||||
|
self.to_vec().first().map(String::to_owned)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
use crate::syntax::content::{Parseable, Token, Lexeme, make_lexmap};
|
|
||||||
|
|
||||||
pub fn read<DefaultToken: Parseable>(text: &str) -> String {
|
|
||||||
let escaped_text = tera::escape_html(text);
|
|
||||||
parse(&lex(&escaped_text, &make_lexmap::<DefaultToken>()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lex(text: &str, map: super::LexMap) -> Vec<Token> {
|
|
||||||
let mut tokens: Vec<Token> = Vec::new();
|
|
||||||
|
|
||||||
for line in text.lines().filter(|x| !x.trim().is_empty()) {
|
|
||||||
let lexeme = Lexeme::new(line);
|
|
||||||
|
|
||||||
for &(ref matcher, lexer) in map {
|
|
||||||
if matcher(&lexeme) {
|
|
||||||
tokens.push(lexer(&lexeme));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse(tokens: &[Token]) -> String {
|
|
||||||
tokens
|
|
||||||
.iter()
|
|
||||||
.map(Token::render)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
}
|
|
||||||
2
src/syntax/content/parsers.rs
Normal file
2
src/syntax/content/parsers.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod line;
|
||||||
|
pub mod word;
|
||||||
33
src/syntax/content/parsers/line.rs
Normal file
33
src/syntax/content/parsers/line.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
use crate::syntax::content::lexeme::Lexeme;
|
||||||
|
|
||||||
|
pub mod parser;
|
||||||
|
pub mod elements;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Line {
|
||||||
|
pub raw: String,
|
||||||
|
pub first: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Line {
|
||||||
|
pub fn new(text: &str) -> Line {
|
||||||
|
let vec: Vec<&str> = text.split(" ").collect();
|
||||||
|
|
||||||
|
Line {
|
||||||
|
raw: text.to_owned(),
|
||||||
|
first: vec.first().unwrap_or_else(|| unreachable!()).to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Lexeme> for Line {
|
||||||
|
fn from(lexeme: Lexeme) -> Line {
|
||||||
|
match lexeme {
|
||||||
|
Lexeme::Word(w) => Line {
|
||||||
|
raw: w.raw.clone(),
|
||||||
|
first: w.raw.split(' ').next().unwrap_or_default().to_owned(),
|
||||||
|
},
|
||||||
|
Lexeme::Line(l) => l,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,8 +32,8 @@ pub struct Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
fn new(level: usize, text: &str) -> Self {
|
fn new(level: usize, text: &str) -> Header {
|
||||||
Self {
|
Header {
|
||||||
level: match level {
|
level: match level {
|
||||||
1 => Level::One,
|
1 => Level::One,
|
||||||
2 => Level::Two,
|
2 => Level::Two,
|
||||||
|
|
@ -52,18 +52,20 @@ impl Header {
|
||||||
|
|
||||||
impl Parseable for Header {
|
impl Parseable for Header {
|
||||||
fn probe(lexeme: &Lexeme) -> bool {
|
fn probe(lexeme: &Lexeme) -> bool {
|
||||||
!lexeme.first.trim().is_empty()
|
let first = lexeme.clone().first().unwrap_or_default();
|
||||||
&& lexeme.first.replace("#", "").is_empty()
|
!first.trim().is_empty()
|
||||||
&& lexeme.first.len() <= 6
|
&& first.replace("#", "").is_empty()
|
||||||
|
&& first.len() <= 6
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lex(lexeme: &Lexeme) -> Self {
|
fn lex(lexeme: &Lexeme) -> Header {
|
||||||
let header_level = lexeme.first.len();
|
let first = lexeme.clone().first().unwrap_or_else(|| unreachable!());
|
||||||
log(&Self::lex, &format!("Header level is {header_level}"));
|
let header_level = &first.len();
|
||||||
|
log(&Header::lex, &format!("Header level is {header_level}"));
|
||||||
|
|
||||||
let header_text = lexeme.raw.replace(lexeme.first, "");
|
let header_text = lexeme.to_raw().replace(&first, "");
|
||||||
|
|
||||||
Self::new(header_level, &header_text)
|
Header::new(*header_level, &header_text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self) -> String {
|
fn render(&self) -> String {
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use crate::syntax::content::{Parseable, Lexeme};
|
use crate::syntax::content::{Parseable, lexeme::Lexeme};
|
||||||
|
|
||||||
pub struct Paragraph {
|
pub struct Paragraph {
|
||||||
text: String,
|
text: String,
|
||||||
|
|
@ -7,12 +7,12 @@ pub struct Paragraph {
|
||||||
|
|
||||||
impl Parseable for Paragraph {
|
impl Parseable for Paragraph {
|
||||||
fn probe(lexeme: &Lexeme) -> bool {
|
fn probe(lexeme: &Lexeme) -> bool {
|
||||||
!lexeme.raw.trim().is_empty()
|
!lexeme.to_raw().trim().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lex(lexeme: &Lexeme) -> Self {
|
fn lex(lexeme: &Lexeme) -> Paragraph {
|
||||||
Self {
|
Paragraph {
|
||||||
text: lexeme.raw.trim().to_owned(),
|
text: lexeme.to_raw().trim().to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use crate::syntax::content::{Parseable, Lexeme};
|
use crate::syntax::content::{Parseable, lexeme::Lexeme};
|
||||||
|
|
||||||
pub struct Span {
|
pub struct Span {
|
||||||
text: String,
|
text: String,
|
||||||
|
|
@ -7,12 +7,12 @@ pub struct Span {
|
||||||
|
|
||||||
impl Parseable for Span {
|
impl Parseable for Span {
|
||||||
fn probe(lexeme: &Lexeme) -> bool {
|
fn probe(lexeme: &Lexeme) -> bool {
|
||||||
!lexeme.raw.trim().is_empty()
|
!lexeme.to_raw().trim().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lex(lexeme: &Lexeme) -> Self {
|
fn lex(lexeme: &Lexeme) -> Span {
|
||||||
Self {
|
Span {
|
||||||
text: lexeme.raw.trim().to_owned(),
|
text: lexeme.to_raw().trim().to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
38
src/syntax/content/parsers/line/parser.rs
Normal file
38
src/syntax/content/parsers/line/parser.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use crate::syntax::content::{
|
||||||
|
LexMap, Line, Parseable, Token, parsers::line::elements::header::Header,
|
||||||
|
make_lexmap, Lexeme,
|
||||||
|
};
|
||||||
|
|
||||||
|
const LEXMAP: LexMap =
|
||||||
|
&[(Header::probe, |line| Token::Header(Header::lex(line)))];
|
||||||
|
|
||||||
|
pub(in crate::syntax::content) fn read<DefaultToken: Parseable>(
|
||||||
|
text: &str,
|
||||||
|
) -> String {
|
||||||
|
parse(&lex(text, &make_lexmap::<DefaultToken>(LEXMAP)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lex(text: &str, map: LexMap) -> Vec<Token> {
|
||||||
|
let mut tokens: Vec<Token> = Vec::new();
|
||||||
|
|
||||||
|
for raw_line in text.lines() {
|
||||||
|
let line = Lexeme::Line(Line::new(raw_line));
|
||||||
|
|
||||||
|
for &(ref probe, lex) in map {
|
||||||
|
if probe(&line) {
|
||||||
|
tokens.push(lex(&line));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(tokens: &[Token]) -> String {
|
||||||
|
tokens
|
||||||
|
.iter()
|
||||||
|
.map(Token::render)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
15
src/syntax/content/parsers/word.rs
Normal file
15
src/syntax/content/parsers/word.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
pub mod parser;
|
||||||
|
pub mod elements;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Word {
|
||||||
|
pub raw: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Word {
|
||||||
|
pub fn new(text: &str) -> Word {
|
||||||
|
Word {
|
||||||
|
raw: text.to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/syntax/content/parsers/word/elements.rs
Normal file
2
src/syntax/content/parsers/word/elements.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod literal;
|
||||||
|
pub mod anchor;
|
||||||
33
src/syntax/content/parsers/word/elements/anchor.rs
Normal file
33
src/syntax/content/parsers/word/elements/anchor.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// use std::fmt::Display;
|
||||||
|
// use crate::syntax::content::{Parseable, Line};
|
||||||
|
//
|
||||||
|
// pub struct Anchor {
|
||||||
|
// text: String,
|
||||||
|
// destination: String,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl Parseable for Anchor {
|
||||||
|
// fn probe(line: &Line) -> bool {
|
||||||
|
// let candidate = line.raw.split(' ');
|
||||||
|
// !line.first.trim().is_empty()
|
||||||
|
// && line.first.replace("#", "").is_empty()
|
||||||
|
// && line.first.len() <= 6
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn lex(line: &Line) -> Self {
|
||||||
|
// Self {
|
||||||
|
// text: line.raw.trim().to_owned(),
|
||||||
|
// destination: t
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn render(&self) -> String {
|
||||||
|
// format!(r#"<a href="{}">{}</a>"#, &self.destination, &self.text)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl Display for Anchor {
|
||||||
|
// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
// write!(f, "Anchor: <{}>", &self.text)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
28
src/syntax/content/parsers/word/elements/literal.rs
Normal file
28
src/syntax/content/parsers/word/elements/literal.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
use std::fmt::Display;
|
||||||
|
use crate::syntax::content::{Parseable, lexeme::Lexeme};
|
||||||
|
|
||||||
|
pub struct Literal {
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parseable for Literal {
|
||||||
|
fn probe(lexeme: &Lexeme) -> bool {
|
||||||
|
!lexeme.to_raw().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lex(lexeme: &Lexeme) -> Literal {
|
||||||
|
Literal {
|
||||||
|
text: lexeme.to_raw().trim().to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self) -> String {
|
||||||
|
self.text.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Literal {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "Literal: <{}>", &self.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/syntax/content/parsers/word/parser.rs
Normal file
37
src/syntax/content/parsers/word/parser.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
use crate::syntax::content::parsers::word::elements::literal::Literal;
|
||||||
|
use crate::syntax::content::{Parseable, Token, Word, LexMap, make_lexmap};
|
||||||
|
use crate::syntax::content::lexeme::Lexeme;
|
||||||
|
|
||||||
|
const LEXMAP: LexMap =
|
||||||
|
&[(Literal::probe, |line| Token::Literal(Literal::lex(line)))];
|
||||||
|
|
||||||
|
pub(in crate::syntax::content) fn read<DefaultToken: Parseable>(
|
||||||
|
text: &str,
|
||||||
|
) -> String {
|
||||||
|
parse(&lex(text, &make_lexmap::<DefaultToken>(LEXMAP)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lex(text: &str, map: LexMap) -> Vec<Token> {
|
||||||
|
let mut tokens: Vec<Token> = Vec::new();
|
||||||
|
|
||||||
|
for raw_word in text.split(" ") {
|
||||||
|
let word = Lexeme::Word(Word::new(raw_word));
|
||||||
|
|
||||||
|
for &(ref probe, lex) in map {
|
||||||
|
if probe(&word) {
|
||||||
|
tokens.push(lex(&word));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(tokens: &[Token]) -> String {
|
||||||
|
tokens
|
||||||
|
.iter()
|
||||||
|
.map(Token::render)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::syntax::content::Parseable as _;
|
use super::Parseable as _;
|
||||||
use crate::syntax::content::elements::{
|
use super::parsers::word::elements::{literal::Literal};
|
||||||
|
use super::parsers::line::elements::{
|
||||||
paragraph::Paragraph, header::Header, span::Span,
|
paragraph::Paragraph, header::Header, span::Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -7,6 +8,7 @@ pub enum Token {
|
||||||
Paragraph(Paragraph),
|
Paragraph(Paragraph),
|
||||||
Header(Header),
|
Header(Header),
|
||||||
Span(Span),
|
Span(Span),
|
||||||
|
Literal(Literal),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
|
|
@ -15,40 +17,31 @@ impl Token {
|
||||||
Token::Paragraph(ref d) => d.render(),
|
Token::Paragraph(ref d) => d.render(),
|
||||||
Token::Header(ref d) => d.render(),
|
Token::Header(ref d) => d.render(),
|
||||||
Token::Span(ref d) => d.render(),
|
Token::Span(ref d) => d.render(),
|
||||||
|
Token::Literal(ref d) => d.render(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Paragraph> for Token {
|
impl From<Paragraph> for Token {
|
||||||
fn from(d: Paragraph) -> Self {
|
fn from(d: Paragraph) -> Token {
|
||||||
Token::Paragraph(d)
|
Token::Paragraph(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Header> for Token {
|
impl From<Header> for Token {
|
||||||
fn from(d: Header) -> Self {
|
fn from(d: Header) -> Token {
|
||||||
Token::Header(d)
|
Token::Header(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Span> for Token {
|
impl From<Span> for Token {
|
||||||
fn from(d: Span) -> Self {
|
fn from(d: Span) -> Token {
|
||||||
Token::Span(d)
|
Token::Span(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Lexeme<'l> {
|
impl From<Literal> for Token {
|
||||||
pub raw: &'l str,
|
fn from(d: Literal) -> Token {
|
||||||
pub first: &'l str,
|
Token::Literal(d)
|
||||||
}
|
|
||||||
|
|
||||||
impl<'l> Lexeme<'l> {
|
|
||||||
pub fn new(text: &'l str) -> Lexeme<'l> {
|
|
||||||
let vec: Vec<&'l str> = text.split(" ").collect();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
raw: text,
|
|
||||||
first: vec.first().unwrap_or_else(|| unreachable!()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ fn mktrue() -> bool {
|
||||||
|
|
||||||
impl Graph {
|
impl Graph {
|
||||||
pub fn new(message: Option<String>) -> Graph {
|
pub fn new(message: Option<String>) -> Graph {
|
||||||
Self {
|
Graph {
|
||||||
nodes: HashMap::new(),
|
nodes: HashMap::new(),
|
||||||
root_node: "VoidNode".to_string(),
|
root_node: "VoidNode".to_string(),
|
||||||
incoming: HashMap::new(),
|
incoming: HashMap::new(),
|
||||||
|
|
@ -128,7 +128,7 @@ impl Graph {
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
pub fn new(message: Option<String>) -> Node {
|
pub fn new(message: Option<String>) -> Node {
|
||||||
Self {
|
Node {
|
||||||
id: "VoidNode".to_string(),
|
id: "VoidNode".to_string(),
|
||||||
title: "Pure Void".to_string(),
|
title: "Pure Void".to_string(),
|
||||||
text: match message {
|
text: match message {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue