summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2023-05-14 12:00:15 +0300
committerLars Wirzenius <liw@liw.fi>2023-05-14 12:20:53 +0300
commitdd5e6c9bab1926836d5989dd9fb153674e8b2ac8 (patch)
tree4f68f05b6444111716209bc145cce69e27b7c644
parente5eee5a3f3327bb9248c9ca47f7e96e3883c965d (diff)
downloadriki-dd5e6c9bab1926836d5989dd9fb153674e8b2ac8.tar.gz
refactor: add a new set-of-pages abstraction
Sponsored-by: author
-rw-r--r--src/page.rs4
-rw-r--r--src/site.rs109
-rw-r--r--src/wikitext.rs6
3 files changed, 69 insertions, 50 deletions
diff --git a/src/page.rs b/src/page.rs
index 485632d..77a06e6 100644
--- a/src/page.rs
+++ b/src/page.rs
@@ -31,7 +31,7 @@ pub enum PageError {
Parser(#[from] crate::parser::ParserError),
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct Page {
meta: PageMeta,
unprocessed: UnprocessedPage,
@@ -90,7 +90,7 @@ impl WikitextPage {
}
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct UnprocessedPage {
meta: PageMeta,
snippets: Vec<Snippet>,
diff --git a/src/site.rs b/src/site.rs
index 58fb374..5196b5c 100644
--- a/src/site.rs
+++ b/src/site.rs
@@ -44,9 +44,8 @@ pub struct Site {
patterns: TokenPatterns,
shortcuts: HashMap<String, Shortcut>,
name_builder: NameBuilder,
- unprocessed_pages: HashMap<PathBuf, Page>,
- markdown_pages: HashMap<PathBuf, MarkdownPage>,
- pages_that_will_exist: PageSet,
+ unprocessed_pages: PageSet<Page>,
+ markdown_pages: PageSet<MarkdownPage>,
files: Names,
}
@@ -60,11 +59,10 @@ impl Site {
{
Self {
name_builder: NameBuilder::new(srcdir.as_ref(), destdir.as_ref()),
- unprocessed_pages: HashMap::new(),
- markdown_pages: HashMap::new(),
+ unprocessed_pages: PageSet::default(),
+ markdown_pages: PageSet::default(),
files: Names::default(),
patterns: TokenPatterns::default(),
- pages_that_will_exist: PageSet::default(),
shortcuts: HashMap::new(),
}
}
@@ -91,7 +89,6 @@ impl Site {
fn add_wikitextpage(&mut self, page: WikitextPage) -> Result<(), SiteError> {
info!("add wikitext page {}", page.meta().path().display());
- self.pages_that_will_exist.insert(&page);
trace!("parsing wikitext page {}", page.meta().path().display());
let mut parser = WikitextParser::new(page.wikitext(), &self.patterns);
@@ -100,7 +97,7 @@ impl Site {
let page = Page::new(page.meta().clone(), page);
self.unprocessed_pages
- .insert(page.meta().path().into(), page);
+ .insert(page.meta().path(), page.clone());
Ok(())
}
@@ -122,13 +119,13 @@ impl Site {
}
fn process_page(&mut self) -> Result<bool, SiteError> {
- if let Some(page) = self.pick_unprocessed_page() {
+ if let Some(page) = self.unprocessed_pages.remove_random_page() {
debug!(
"processing unprocessed page {}",
page.meta().path().display()
);
let page = page.markdown(self)?;
- self.markdown_pages.insert(page.meta().path().into(), page);
+ self.markdown_pages.insert(page.meta().path(), page.clone());
Ok(true)
} else {
trace!("no pages to process");
@@ -136,17 +133,8 @@ impl Site {
}
}
- fn pick_unprocessed_page(&mut self) -> Option<Page> {
- let mut keys: Vec<PathBuf> = self.unprocessed_pages.keys().map(|k| k.into()).collect();
- if let Some(path) = keys.pop() {
- self.unprocessed_pages.remove(&path)
- } else {
- None
- }
- }
-
pub fn markdown_pages(&self) -> impl Iterator<Item = &MarkdownPage> {
- self.markdown_pages.values()
+ self.markdown_pages.pages()
}
pub fn files_only(&self) -> impl Iterator<Item = &Name> {
@@ -158,14 +146,11 @@ impl Site {
}
pub fn is_page(&self, path: &Path) -> bool {
- self.unprocessed_pages.contains_key(path) || self.markdown_pages.contains_key(path)
+ self.unprocessed_pages.contains(path) || self.markdown_pages.contains(path)
}
pub fn page(&self, path: &Path) -> Option<&MarkdownPage> {
- self.markdown_pages
- .iter()
- .find(|(page_path, _)| page_path.as_path() == path)
- .map(|(_, md)| md)
+ self.markdown_pages.get_page(path)
}
fn all_files(&self) -> Result<Vec<Name>, SiteError> {
@@ -224,9 +209,9 @@ impl Site {
// Is target absolute?
if target.starts_with("/") {
- if let Some(path) = self.pages_that_will_exist.get_path(target) {
+ if self.is_page(target) {
trace!("absolute target exists");
- return Ok(path.into());
+ return Ok(target.into());
} else {
trace!("absolute target does not exist");
return Err(SiteError::PageMissing(page.into(), target.into()));
@@ -236,9 +221,9 @@ impl Site {
// Does a sub-page or file exist?
let wanted = page.join(target);
trace!("checking for subpage or file {}", wanted.display());
- if let Some(path) = self.pages_that_will_exist.get_path(&wanted) {
- trace!("subpage exists: {}", path.display());
- return Ok(path.into());
+ if self.is_page(&wanted) {
+ trace!("subpage exists: {}", wanted.display());
+ return Ok(wanted);
} else if self.file_exists(&wanted) {
trace!("subpage file exists: {}", wanted.display());
return Ok(wanted);
@@ -252,9 +237,13 @@ impl Site {
parent.display(),
path.display()
);
- if let Some(path) = self.pages_that_will_exist.get_path(path.as_path()) {
- trace!("sibling page exists: {}", path.display());
- return Ok(path.into());
+ if let Some(actual) = self.unprocessed_pages.get_path(&path) {
+ trace!("sibling page exists: {}", actual.display());
+ return Ok(actual.into());
+ }
+ if let Some(actual) = self.markdown_pages.get_path(&path) {
+ trace!("sibling page exists: {}", actual.display());
+ return Ok(actual.into());
}
// trace!("consider files: {:?}", self.files);
if self.file_exists(&path) {
@@ -266,9 +255,9 @@ impl Site {
// Does target exist relative to root?
let wanted = Path::new("/").join(target);
trace!("checking for absolute path {}", wanted.display());
- if let Some(path) = self.pages_that_will_exist.get_path(&wanted) {
- trace!("page at absolute path exists: {}", path.display());
- return Ok(path.into());
+ if self.is_page(&wanted) {
+ trace!("page at absolute path exists: {}", wanted.display());
+ return Ok(wanted);
} else if self.file_exists(&wanted) {
trace!("file at absolute path exists: {}", wanted.display());
return Ok(wanted);
@@ -301,20 +290,42 @@ impl Site {
}
}
-#[derive(Default, Debug)]
-struct PageSet {
- map: HashMap<String, PathBuf>,
+#[derive(Debug)]
+struct PageSet<T> {
+ map: HashMap<String, (PathBuf, T)>,
}
-impl PageSet {
- fn insert(&mut self, page: &WikitextPage) {
- let path = page.meta().path();
+impl<T> PageSet<T> {
+ fn insert(&mut self, path: &Path, page: T) {
let key = Self::normalize(path);
- self.map.insert(key, path.into());
+ self.map.insert(key, (path.into(), page));
+ }
+
+ fn contains(&self, path: &Path) -> bool {
+ self.map.contains_key(&Self::normalize(path))
+ }
+
+ fn get_page(&self, path: &Path) -> Option<&T> {
+ self.map.get(&Self::normalize(path)).map(|(_, page)| page)
}
- fn get_path(&self, path: &Path) -> Option<&Path> {
- self.map.get(&Self::normalize(path)).map(|x| x.as_ref())
+ fn get_path(&self, wanted: &Path) -> Option<&Path> {
+ self.map
+ .get(&Self::normalize(wanted))
+ .map(|(path, _)| path.as_path())
+ }
+
+ fn pages(&self) -> impl Iterator<Item = &T> {
+ self.map.values().map(|(_, page)| page)
+ }
+
+ fn remove_random_page(&mut self) -> Option<T> {
+ let mut keys: Vec<String> = self.map.keys().take(1).map(|k| k.into()).collect();
+ if let Some(key) = keys.pop() {
+ self.map.remove(&key).map(|(_, page)| page)
+ } else {
+ None
+ }
}
fn normalize(path: &Path) -> String {
@@ -322,6 +333,14 @@ impl PageSet {
}
}
+impl<T> Default for PageSet<T> {
+ fn default() -> Self {
+ Self {
+ map: HashMap::default(),
+ }
+ }
+}
+
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Shortcut {
name: String,
diff --git a/src/wikitext.rs b/src/wikitext.rs
index 57dff88..4192c85 100644
--- a/src/wikitext.rs
+++ b/src/wikitext.rs
@@ -14,7 +14,7 @@ pub enum WikitextError {
Site(#[from] crate::site::SiteError),
}
-#[derive(Debug, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Snippet {
Markdown(String),
WikiLink(WikiLink),
@@ -69,7 +69,7 @@ impl Snippet {
}
}
-#[derive(Debug, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub struct WikiLink {
link_text: String,
target: String,
@@ -92,7 +92,7 @@ impl WikiLink {
}
}
-#[derive(Debug, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ParsedDirective {
name: String,
args: HashMap<String, String>,