Allow specifying redirects as path start and end

This commit is contained in:
Joscha 2022-10-22 19:30:44 +02:00
parent 0e3d61d632
commit e91a2db1b1
2 changed files with 26 additions and 3 deletions

View file

@ -11,12 +11,22 @@ fn find_index_of_title(pages: &[Page<PageInfo>], title: &str) -> u32 {
pages pages
.iter() .iter()
.enumerate() .enumerate()
.filter(|(_, p)| !p.data.redirect)
.find(|(_, p)| util::normalize_link(&p.data.title) == title) .find(|(_, p)| util::normalize_link(&p.data.title) == title)
.map(|(i, _)| i) .map(|(i, _)| i)
.expect("invalid title") as u32 .expect("invalid title") as u32
} }
fn resolve_redirects(data: &AdjacencyList<PageInfo, LinkInfo>, 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 { struct DijkstraPageInfo {
cost: u32, cost: u32,
prev_page_idx: 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(); let pages = data.pages.clone();
println!(">> Locate from and to"); println!(">> Locate from and to");
let from_idx = find_index_of_title(&pages, from); let from_idx = resolve_redirects(&data, find_index_of_title(&pages, from));
let to_idx = find_index_of_title(&pages, to); let to_idx = resolve_redirects(&data, find_index_of_title(&pages, to));
println!(">> Find path"); println!(">> Find path");
let path = dijkstra(data, from_idx, to_idx); let path = dijkstra(data, from_idx, to_idx);

View file

@ -214,6 +214,19 @@ impl AdjacencyList<PageInfo, LinkInfo> {
panic!("Invalid link detected!"); 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);
}
}
}
} }
} }