From d0ff505c89cf6d71c4ba4754af3c71d7f133036e Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 7 Jan 2023 11:31:38 +0200 Subject: refactor: move directive errors to src/directive/mod.rs Sponsored-by: author --- src/directive/calendar.rs | 7 +++--- src/directive/format.rs | 7 +++--- src/directive/graph.rs | 7 +++--- src/directive/img.rs | 9 ++++---- src/directive/inline.rs | 7 +++--- src/directive/map.rs | 7 +++--- src/directive/meta.rs | 7 +++--- src/directive/mod.rs | 54 +++++++++++++++++++++++++++++++++++----------- src/directive/pagestats.rs | 7 +++--- src/directive/shortcut.rs | 7 +++--- src/directive/sidebar.rs | 7 +++--- src/directive/table.rs | 5 ++--- src/directive/tag.rs | 5 ++--- src/directive/toc.rs | 7 +++--- src/directive/traillink.rs | 7 +++--- src/error.rs | 21 +++--------------- src/wikitext.rs | 7 +++--- 17 files changed, 91 insertions(+), 87 deletions(-) diff --git a/src/directive/calendar.rs b/src/directive/calendar.rs index 64298f6..233a742 100644 --- a/src/directive/calendar.rs +++ b/src/directive/calendar.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -24,7 +23,7 @@ impl DirectiveImplementation for Calendar { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("calendar".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("calendar".into())) } } diff --git a/src/directive/format.rs b/src/directive/format.rs index fbfdde6..0d89361 100644 --- a/src/directive/format.rs +++ b/src/directive/format.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for Format { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("format".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("format".into())) } } diff --git a/src/directive/graph.rs b/src/directive/graph.rs index 12d3c66..21f91aa 100644 --- a/src/directive/graph.rs +++ b/src/directive/graph.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for Graph { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("graph".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("graph".into())) } } diff --git a/src/directive/img.rs b/src/directive/img.rs index 843975c..a931650 100644 --- a/src/directive/img.rs +++ b/src/directive/img.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -82,13 +81,15 @@ impl DirectiveImplementation for Img { img } - fn process(&self, site: &Site, meta: &mut PageMeta) -> Result { + fn process(&self, site: &Site, meta: &mut PageMeta) -> Result { trace!( "verify image exists: {} on {}", self.src, meta.path().display() ); - let src = site.resolve(meta.path(), Path::new(&self.src))?; + let src = site + .resolve(meta.path(), Path::new(&self.src)) + .map_err(|e| DirectiveError::Riki(Box::new(e)))?; trace!("img src={:?}", src.display()); let mut img = String::new(); diff --git a/src/directive/inline.rs b/src/directive/inline.rs index 5afc02c..973890b 100644 --- a/src/directive/inline.rs +++ b/src/directive/inline.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::pagespec::PageSpec; use crate::site::Site; @@ -38,8 +37,8 @@ impl DirectiveImplementation for Inline { Inline::new(pages.to_string()) } - fn process(&self, site: &Site, meta: &mut PageMeta) -> Result { - let pagespec = PageSpec::new(meta.path(), &self.pages)?; + fn process(&self, site: &Site, meta: &mut PageMeta) -> Result { + let pagespec = PageSpec::new(meta.path(), &self.pages).map_err(DirectiveError::PageSpec)?; let matches: Vec = site .markdown_pages() .iter() diff --git a/src/directive/map.rs b/src/directive/map.rs index 5a9d2ae..5d784ab 100644 --- a/src/directive/map.rs +++ b/src/directive/map.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for Map { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("map".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("map".into())) } } diff --git a/src/directive/meta.rs b/src/directive/meta.rs index 00f2372..7524bef 100644 --- a/src/directive/meta.rs +++ b/src/directive/meta.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::time::parse_timestamp; @@ -28,12 +27,12 @@ impl DirectiveImplementation for Meta { meta } - fn process(&self, _site: &Site, meta: &mut PageMeta) -> Result { + fn process(&self, _site: &Site, meta: &mut PageMeta) -> Result { if let Some(title) = &self.title { meta.set_title(title.into()); } if let Some(mtime) = &self.date { - meta.set_mtime(parse_timestamp(mtime)?); + meta.set_mtime(parse_timestamp(mtime).map_err(|e| DirectiveError::Riki(Box::new(e)))?); } Ok(Processed::Markdown("".into())) } diff --git a/src/directive/mod.rs b/src/directive/mod.rs index dd9eedb..4edda32 100644 --- a/src/directive/mod.rs +++ b/src/directive/mod.rs @@ -1,4 +1,3 @@ -use crate::error::RikiError; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -6,6 +5,33 @@ use crate::wikitext::ParsedDirective; use log::{debug, trace}; use std::collections::HashSet; +#[derive(Debug, thiserror::Error)] +pub enum DirectiveError { + #[error("unknown directive {0}")] + UnknownDirective(String), + + #[error("directive {0} is missing required argument {1}")] + DirectiveMissingArg(String, String), + + #[error("directive {0} has unknown argument {1}")] + DirectiveUnknownArg(String, String), + + #[error("directive {0} does not allow unnamed arguments")] + UnknownArgsNotAllowed(String), + + #[error("directive isn't implemented yet: {0}")] + UnimplementedDirective(String), + + #[error("toc directive arguments 'levels' could not be parsed as an integer: {0}")] + LevelsParse(String, #[source] std::num::ParseIntError), + + #[error(transparent)] + PageSpec(#[from] crate::pagespec::PageSpecError), + + #[error(transparent)] + Riki(#[from] Box), +} + pub enum Processed { Markdown(String), Toc(usize), @@ -17,9 +43,9 @@ pub trait DirectiveImplementation { const ALLOW_ANY_UNNAMED: bool; fn from_parsed(p: &ParsedDirective) -> Self; - fn process(&self, site: &Site, meta: &mut PageMeta) -> Result; + fn process(&self, site: &Site, meta: &mut PageMeta) -> Result; - fn prepare(&self, _site: &mut Site) -> Result<(), RikiError> { + fn prepare(&self, _site: &mut Site) -> Result<(), DirectiveError> { Ok(()) } } @@ -49,7 +75,7 @@ pub enum Directive { } impl TryFrom for Directive { - type Error = RikiError; + type Error = DirectiveError; fn try_from(p: ParsedDirective) -> Result { Self::try_from(&p) @@ -57,7 +83,7 @@ impl TryFrom for Directive { } impl TryFrom<&ParsedDirective> for Directive { - type Error = RikiError; + type Error = DirectiveError; fn try_from(p: &ParsedDirective) -> Result { let d = match p.name() { @@ -173,7 +199,7 @@ impl TryFrom<&ParsedDirective> for Directive { )?; Directive::TrailLink(TrailLink::from_parsed(p)) } - _ => return Err(RikiError::UnknownDirective(p.name().into())), + _ => return Err(DirectiveError::UnknownDirective(p.name().into())), }; Ok(d) } @@ -185,11 +211,11 @@ impl Directive { required: &[&str], allowed: &[&str], allow_any_unnamed: bool, - ) -> Result<(), RikiError> { + ) -> Result<(), DirectiveError> { let args = p.args(); for arg in required.iter() { if !args.contains_key(arg) { - return Err(RikiError::DirectiveMissingArg( + return Err(DirectiveError::DirectiveMissingArg( p.name().into(), arg.to_string(), )); @@ -201,11 +227,11 @@ impl Directive { for (arg, value) in p.args().iter() { if value.is_empty() { if !allow_any_unnamed { - return Err(RikiError::UnknownArgsNotAllowed(p.name().into())); + return Err(DirectiveError::UnknownArgsNotAllowed(p.name().into())); } } else if !allowed.contains(*arg) { debug!("parsed directive {:?}", p); - return Err(RikiError::DirectiveUnknownArg( + return Err(DirectiveError::DirectiveUnknownArg( p.name().into(), arg.to_string(), )); @@ -214,7 +240,7 @@ impl Directive { Ok(()) } - pub fn prepare(&self, site: &mut Site) -> Result<(), RikiError> { + pub fn prepare(&self, site: &mut Site) -> Result<(), DirectiveError> { trace!("prepare directive {:?}", self); if let Self::Shortcut(x) = self { x.prepare(site)?; @@ -222,7 +248,11 @@ impl Directive { Ok(()) } - pub fn process(&self, site: &mut Site, meta: &mut PageMeta) -> Result { + pub fn process( + &self, + site: &mut Site, + meta: &mut PageMeta, + ) -> Result { match self { Self::Simple | Self::UnnamedArg diff --git a/src/directive/pagestats.rs b/src/directive/pagestats.rs index 1971a16..eb3b595 100644 --- a/src/directive/pagestats.rs +++ b/src/directive/pagestats.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for PageStats { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("pagestat".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("pagestat".into())) } } diff --git a/src/directive/shortcut.rs b/src/directive/shortcut.rs index 8c5009d..3bbd6a6 100644 --- a/src/directive/shortcut.rs +++ b/src/directive/shortcut.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::{Shortcut as S, Site}; use crate::wikitext::ParsedDirective; @@ -24,13 +23,13 @@ impl DirectiveImplementation for Shortcut { Self::new(S::new(name, desc, url)) } - fn prepare(&self, site: &mut Site) -> Result<(), RikiError> { + fn prepare(&self, site: &mut Site) -> Result<(), DirectiveError> { trace!("shortcut: prepare"); site.add_shortcut(self.shortcut.clone()); Ok(()) } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { Ok(Processed::Markdown("".into())) } } diff --git a/src/directive/sidebar.rs b/src/directive/sidebar.rs index c7a3ca8..630ef1f 100644 --- a/src/directive/sidebar.rs +++ b/src/directive/sidebar.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for Sidebar { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("sidebar".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("sidebar".into())) } } diff --git a/src/directive/table.rs b/src/directive/table.rs index 3039516..4f1b9ca 100644 --- a/src/directive/table.rs +++ b/src/directive/table.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -19,7 +18,7 @@ impl DirectiveImplementation for Table { Self::new(p.args().get("data").unwrap().to_string()) } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { let mut table = String::new(); let mut lines = self.data.trim().lines(); if let Some(first) = lines.next() { diff --git a/src/directive/tag.rs b/src/directive/tag.rs index b6708ef..6439199 100644 --- a/src/directive/tag.rs +++ b/src/directive/tag.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -19,7 +18,7 @@ impl DirectiveImplementation for Tag { Tag::new(tags) } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { Ok(Processed::Markdown("".into())) } } diff --git a/src/directive/toc.rs b/src/directive/toc.rs index 4425e6e..fa115b6 100644 --- a/src/directive/toc.rs +++ b/src/directive/toc.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::html::{Content, Element, ElementTag}; use crate::page::PageMeta; use crate::site::Site; @@ -21,11 +20,11 @@ impl DirectiveImplementation for Toc { Self::new(levels.to_string()) } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { let levels: usize = self .levels .parse() - .map_err(|e| RikiError::LevelsParse(self.levels.clone(), e))?; + .map_err(|e| DirectiveError::LevelsParse(self.levels.clone(), e))?; Ok(Processed::Toc(levels)) } } diff --git a/src/directive/traillink.rs b/src/directive/traillink.rs index d7ed8d8..9f880dc 100644 --- a/src/directive/traillink.rs +++ b/src/directive/traillink.rs @@ -1,5 +1,4 @@ -use crate::directive::{DirectiveImplementation, Processed}; -use crate::error::RikiError; +use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; @@ -16,7 +15,7 @@ impl DirectiveImplementation for TrailLink { Self::default() } - fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { - Err(RikiError::UnimplementedDirective("traillink".into())) + fn process(&self, _site: &Site, _meta: &mut PageMeta) -> Result { + Err(DirectiveError::UnimplementedDirective("traillink".into())) } } diff --git a/src/error.rs b/src/error.rs index 3bbdb2c..6d4d13b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,24 +15,15 @@ pub enum RikiError { #[error(transparent)] Page(#[from] crate::page::PageError), + #[error(transparent)] + Directive(#[from] crate::directive::DirectiveError), + #[error("string formatting error: {0}")] Format(#[source] std::fmt::Error), - #[error("unknown directive {0}")] - UnknownDirective(String), - - #[error("directive {0} does not allow unnamed arguments")] - UnknownArgsNotAllowed(String), - #[error("directive {0} has more than one unnamed argument")] TooManyUnnamedArgs(String), - #[error("directive {0} is missing required argument {1}")] - DirectiveMissingArg(String, String), - - #[error("directive {0} has unknown argument {1}")] - DirectiveUnknownArg(String, String), - #[error("link to missing page {1} on {0}")] PageMissing(PathBuf, PathBuf), @@ -48,12 +39,6 @@ pub enum RikiError { #[error("failed to parse wikitext, line {0}, column {1}: {2:?}")] WikitextSyntax(usize, usize, Vec), - #[error("directive isn't implemented yet: {0}")] - UnimplementedDirective(String), - - #[error("toc directive arguments 'levels' could not be parsed as an integer: {0}")] - LevelsParse(String, #[source] std::num::ParseIntError), - #[error(transparent)] HtmlError(#[from] HtmlError), } diff --git a/src/wikitext.rs b/src/wikitext.rs index 2561ce5..f8f4ce6 100644 --- a/src/wikitext.rs +++ b/src/wikitext.rs @@ -44,14 +44,15 @@ impl Snippet { Snippet::Directive(p) => { let e = Directive::try_from(p); if let Ok(d) = e { - d.process(site, meta) - .map_err(|e| RikiError::PageProblem(meta.path().into(), Box::new(e)))? + d.process(site, meta).map_err(|e| { + RikiError::PageProblem(meta.path().into(), Box::new(e.into())) + })? } else if let Some(shortcut) = site.shortcut(p.name()) { let arg = p.unnamed_args().first().unwrap().to_string(); let link = format!("[{}]({})", shortcut.desc(&arg), shortcut.url(&arg)); Processed::Markdown(link) } else { - return Err(e.unwrap_err()); + return Err(e.unwrap_err().into()); } } }; -- cgit v1.2.1