diff --git a/brood/src/commands/path.rs b/brood/src/commands/path.rs index 4193c09..53bbbad 100644 --- a/brood/src/commands/path.rs +++ b/brood/src/commands/path.rs @@ -11,12 +11,22 @@ fn find_index_of_title(pages: &[Page], title: &str) -> u32 { pages .iter() .enumerate() - .filter(|(_, p)| !p.data.redirect) .find(|(_, p)| util::normalize_link(&p.data.title) == title) .map(|(i, _)| i) .expect("invalid title") as u32 } +fn resolve_redirects(data: &AdjacencyList, mut page_idx: u32) -> u32 { + loop { + let page = &data.page(page_idx); + if page.data.redirect { + page_idx = data.link(page.link_idx).to; + } else { + break page_idx; + } + } +} + struct DijkstraPageInfo { cost: u32, prev_page_idx: u32, @@ -145,8 +155,8 @@ pub fn path(datafile: &Path, from: &str, to: &str) -> io::Result<()> { let pages = data.pages.clone(); println!(">> Locate from and to"); - let from_idx = find_index_of_title(&pages, from); - let to_idx = find_index_of_title(&pages, to); + let from_idx = resolve_redirects(&data, find_index_of_title(&pages, from)); + let to_idx = resolve_redirects(&data, find_index_of_title(&pages, to)); println!(">> Find path"); let path = dijkstra(data, from_idx, to_idx); diff --git a/brood/src/data.rs b/brood/src/data.rs index f6e86ea..0ab5c78 100644 --- a/brood/src/data.rs +++ b/brood/src/data.rs @@ -214,6 +214,19 @@ impl AdjacencyList { panic!("Invalid link detected!"); } } + + // Check that all redirect pages have exactly one link + for page_idx in 0..self.pages.len() as u32 - 1 { + let page = self.page(page_idx); + if page.data.redirect { + let start_idx = page.link_idx; + let end_idx = self.page(page_idx + 1).link_idx; + let n_links = end_idx - start_idx; + if n_links != 1 { + panic!("Redirect {:?} has {n_links} links", page.data.title); + } + } + } } }