use crate::directive::{DirectiveError, DirectiveImplementation, Processed}; use crate::page::PageMeta; use crate::pagespec::PageSpec; use crate::site::Site; use crate::util::make_relative_link; use crate::wikitext::ParsedDirective; use std::path::Path; #[derive(Debug, Default, Eq, PartialEq)] pub struct PageStats { pages: String, } impl DirectiveImplementation for PageStats { const REQUIRED: &'static [&'static str] = &["pages"]; const ALLOWED: &'static [&'static str] = &["among", "style"]; const ALLOW_ANY_UNNAMED: bool = true; fn from_parsed(p: &ParsedDirective) -> Self { let args = p.args(); let pages = args.get("pages").unwrap(); Self::new(pages.to_string()) } 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() .filter(|page| pagespec.matches(site, page.meta().path())) .map(|page| format!("* {}\n", Self::link(meta.path(), page.meta()))) .collect(); Ok(Processed::Markdown(matches.join(""))) } } impl PageStats { pub fn new(pages: String) -> Self { Self { pages } } fn link(container: &Path, meta: &PageMeta) -> String { let link = make_relative_link(container, meta.path()); format!("[{}]({})", meta.title(), link.display()) } }