From 88dfede79db8eaf17c919543bb41ab4aae3a2be8 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 23 Oct 2022 11:28:12 +0300 Subject: fix: return error for wikitext syntax errors, instead of panic Sponsored-by: author --- src/error.rs | 10 ++++++++++ src/parser.rs | 38 ++++++++------------------------------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/error.rs b/src/error.rs index 2a7d373..922f735 100644 --- a/src/error.rs +++ b/src/error.rs @@ -85,4 +85,14 @@ pub enum SiteError { #[error(transparent)] PageSpec(#[from] crate::pagespec::PageSpecError), + + #[error("failed to parse wikitext, line {0}, column {1}: {2:?}")] + WikitextSyntax(usize, usize, Vec), +} + +impl SiteError { + pub fn wikitext_syntax(line: usize, col: usize, tokens: &[crate::token::TokenKind]) -> Self { + let tokens = tokens.to_vec(); + Self::WikitextSyntax(line, col, tokens) + } } diff --git a/src/parser.rs b/src/parser.rs index 5378f36..559ee3a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -52,8 +52,7 @@ impl WikitextParser { let (line, col) = self.position(); debug!("token at {}:{}", line, col); let snippet = match &self.tokens[..] { - [TokenKind::OpenBrackets, TokenKind::Word(target), TokenKind::CloseBrackets, ..] => - { + [TokenKind::OpenBrackets, TokenKind::Word(target), TokenKind::CloseBrackets, ..] => { let wikilink = WikiLink::new(target, target); let snippet = Snippet::WikiLink(wikilink); self.drain(3); @@ -98,8 +97,7 @@ impl WikitextParser { self.drain(1); break; } - [TokenKind::Pipe, TokenKind::Word(word), TokenKind::CloseBrackets, ..] => - { + [TokenKind::Pipe, TokenKind::Word(word), TokenKind::CloseBrackets, ..] => { trace!("match |{:?}]]", word); target = Some(word.to_string()); self.drain(3); @@ -112,12 +110,7 @@ impl WikitextParser { self.drain(3); break; } - _ => panic!( - "a can't parse line {} column {}: {:?}", - line, - col, - &self.tokens[..5] - ), + _ => return Err(SiteError::wikitext_syntax(line, col, &self.tokens[..5])), } } if target.is_none() { @@ -126,8 +119,7 @@ impl WikitextParser { let wikilink = WikiLink::new(&link_text, &target.unwrap()); Snippet::WikiLink(wikilink) } - [TokenKind::OpenBrackets, TokenKind::Bang, TokenKind::Word(name), ..] => - { + [TokenKind::OpenBrackets, TokenKind::Bang, TokenKind::Word(name), ..] => { trace!("match [[!{:?}", name); let name = name.to_string(); let mut args = HashMap::new(); @@ -155,8 +147,7 @@ impl WikitextParser { self.drain(2); break; } - [TokenKind::Word(name), TokenKind::Equals, TokenKind::Word(value), ..] => - { + [TokenKind::Word(name), TokenKind::Equals, TokenKind::Word(value), ..] => { trace!("match {:?}={:?}", name, value); args.insert(name.to_string(), value.to_string()); self.drain(3); @@ -172,12 +163,7 @@ impl WikitextParser { args.insert(value.to_string(), "".to_string()); self.drain(1); } - _ => panic!( - "b can't parse line {} column {}: {:?}", - line, - col, - &self.tokens[..5] - ), + _ => return Err(SiteError::wikitext_syntax(line, col, &self.tokens[..5])), } } Snippet::Directive(ParsedDirective::new(&name, args)?) @@ -204,12 +190,7 @@ impl WikitextParser { self.drain(4); break; } - _ => panic!( - "c can't parse line {} column {}: {:?}", - line, - col, - &self.tokens[..5] - ), + _ => return Err(SiteError::wikitext_syntax(line, col, &self.tokens[..5])), } } Snippet::Markdown(format!("![{}]({})", link_text, target.unwrap())) @@ -275,10 +256,7 @@ impl WikitextParser { self.drain(1); Snippet::Markdown("]]".into()) } - _ => panic!( - "d can't parse line {} column {}: {:?}", - line, col, self.tokens - ), + _ => return Err(SiteError::wikitext_syntax(line, col, &self.tokens[..5])), }; Ok(Some(snippet)) } -- cgit v1.2.1