readable errors
This commit is contained in:
10
src/main.rs
10
src/main.rs
@@ -37,7 +37,7 @@ fn main() {
|
||||
let specs = &args[2..];
|
||||
let src = || std::fs::read_to_string(&args[0]).unwrap();
|
||||
match args[1].to_lowercase().trim() {
|
||||
"html" => println!(
|
||||
"html" => print!(
|
||||
"{}",
|
||||
to::html::page(&parse(&src()).unwrap(), specs, &mut to::html::State::new())
|
||||
),
|
||||
@@ -122,7 +122,13 @@ const BODY_REGEX = new RegExp("<bo"+"dy>.*<\\/bo"+"dy>", "misv");
|
||||
}
|
||||
buf1[i] = src();
|
||||
let src = unsafe { &*((&buf1[i]) as *const String) };
|
||||
buf2[i] = Some(parse(src).unwrap());
|
||||
buf2[i] = Some(match parse(src) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.display(src));
|
||||
continue;
|
||||
}
|
||||
});
|
||||
let doc = unsafe { &*(buf2[i].as_ref().unwrap() as *const Document<'_>) };
|
||||
i += 1;
|
||||
let mut http =
|
||||
|
||||
72
src/parse.rs
72
src/parse.rs
@@ -1,3 +1,5 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::doc::{Component, Document, Section, Text};
|
||||
|
||||
pub fn parse<'a>(mut src: &'a str) -> Result<Document<'a>, ParseError<'a>> {
|
||||
@@ -6,6 +8,8 @@ pub fn parse<'a>(mut src: &'a str) -> Result<Document<'a>, ParseError<'a>> {
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParseErrorPlus<'a>(ParseErr<'a>, usize, &'a str);
|
||||
#[derive(Debug)]
|
||||
pub struct ParseError<'a>(ParseErr<'a>, usize);
|
||||
#[derive(Debug)]
|
||||
@@ -20,7 +24,7 @@ pub enum ParseErr<'a> {
|
||||
MissingClosing(char),
|
||||
InvalidBacktickBracketCountSpecifier,
|
||||
InvalidBacktickModifier,
|
||||
SubsectionNotAllowedHere,
|
||||
SubdocumentNotAllowedHere,
|
||||
FileTitleWithLink,
|
||||
r#__Zzzz(&'a str),
|
||||
}
|
||||
@@ -371,7 +375,7 @@ fn parse_sections<'a>(
|
||||
// => section hashes
|
||||
Some(' ' | '\n') | None => {
|
||||
if !document {
|
||||
return Err(ParseError(ParseErr::SubsectionNotAllowedHere, pos));
|
||||
return Err(ParseError(ParseErr::SubdocumentNotAllowedHere, pos));
|
||||
}
|
||||
src.reset_to(pos);
|
||||
match parse_document(src.get(), depth + 1)
|
||||
@@ -517,3 +521,67 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ParseError<'a> {
|
||||
pub fn display(self, src: &'a str) -> ParseErrorPlus<'a> {
|
||||
ParseErrorPlus(self.0, self.1, src)
|
||||
}
|
||||
}
|
||||
impl<'a> Display for ParseErrorPlus<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let ln = self
|
||||
.2
|
||||
.char_indices()
|
||||
.take_while(|(i, _)| *i <= self.1)
|
||||
.filter(|(_, c)| *c == '\n')
|
||||
.count();
|
||||
write!(f, "Line {}: {}", ln + 1, self.0)
|
||||
}
|
||||
}
|
||||
impl<'a> Display for ParseErr<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ParseErr::InvalidSectionHash => write!(
|
||||
f,
|
||||
"this section hash isn't valid, if you want a title, add a space after your hashtags"
|
||||
),
|
||||
ParseErr::InvalidHeadingDepth => write!(f, "this heading depth isn't allowed here"),
|
||||
ParseErr::BracketsAtStartOfSectionWithNoLinebreakAfter => write!(
|
||||
f,
|
||||
"brackets at the start of a section must be on their own line"
|
||||
),
|
||||
ParseErr::BracketedSectionNotTerminated => {
|
||||
write!(f, "this bracketed section isn't terminated anywhere")
|
||||
}
|
||||
ParseErr::BracketedSectionTerminatedByTooManyBrackets => write!(
|
||||
f,
|
||||
"this bracketed section is terminated by more brackets than expected"
|
||||
),
|
||||
ParseErr::IncompleteBacktick => {
|
||||
write!(
|
||||
f,
|
||||
"incomplete backtick, there needs to be something here (or escape the backtick: ``)"
|
||||
)
|
||||
}
|
||||
ParseErr::MissingClosing(c) => {
|
||||
write!(f, "couldn't find an appropriate closing {c} bracket")
|
||||
}
|
||||
ParseErr::InvalidBacktickBracketCountSpecifier => write!(
|
||||
f,
|
||||
"invalid backtick bracket count between ` and the next ascii symbol"
|
||||
),
|
||||
ParseErr::InvalidBacktickModifier => write!(
|
||||
f,
|
||||
"invalid backtick modifier between ` and the next bracket"
|
||||
),
|
||||
ParseErr::SubdocumentNotAllowedHere => {
|
||||
write!(f, "found a subdocument where it isn't allowed")
|
||||
}
|
||||
ParseErr::FileTitleWithLink => write!(
|
||||
f,
|
||||
"file title (title at the start of the file) cannot have a link"
|
||||
),
|
||||
ParseErr::__Zzzz(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,13 @@ use crate::{
|
||||
|
||||
pub struct State<'a> {
|
||||
pub head_to_body: &'a str,
|
||||
cache_docs: BTreeMap<&'a Document<'a>, String>,
|
||||
cache_secs: BTreeMap<&'a Section<'a>, String>,
|
||||
cache: BTreeMap<&'a Section<'a>, String>,
|
||||
}
|
||||
impl<'a> State<'a> {
|
||||
pub fn new() -> Self {
|
||||
State {
|
||||
head_to_body: "</head>\n<body>",
|
||||
cache_docs: Default::default(),
|
||||
cache_secs: Default::default(),
|
||||
cache: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,11 +252,6 @@ fn doc_to_impl<'a>(
|
||||
out: &mut String,
|
||||
doc_args: &mut DocArgs<'a, '_>,
|
||||
) {
|
||||
if let Some(prev) = doc_args.state.cache_docs.get(doc) {
|
||||
out.push_str(prev);
|
||||
return;
|
||||
}
|
||||
let out_start = out.len();
|
||||
let depth = doc_args.depth;
|
||||
let end_at = doc_args.max_len.map(|len| out.len() + len);
|
||||
for d in depth..=doc.depth {
|
||||
@@ -285,7 +278,7 @@ fn doc_to_impl<'a>(
|
||||
out.push_str(&format!("</span>{a}</div>\n"));
|
||||
}
|
||||
for section in &doc.sections {
|
||||
if let Some(prev) = doc_args.state.cache_secs.get(section) {
|
||||
if let Some(prev) = doc_args.state.cache.get(section) {
|
||||
out.push_str(prev);
|
||||
continue;
|
||||
}
|
||||
@@ -385,16 +378,12 @@ fn doc_to_impl<'a>(
|
||||
out.push_str("</div>\n");
|
||||
doc_args
|
||||
.state
|
||||
.cache_secs
|
||||
.cache
|
||||
.insert(section, out[section_start..].to_owned());
|
||||
}
|
||||
for _ in depth..=doc.depth {
|
||||
out.push_str("</div>\n");
|
||||
}
|
||||
doc_args
|
||||
.state
|
||||
.cache_docs
|
||||
.insert(doc, out[out_start..].to_owned());
|
||||
}
|
||||
|
||||
fn text_to<'a: 'b, 'b>(
|
||||
|
||||
Reference in New Issue
Block a user