diff --git a/brood/src/commands/path.rs b/brood/src/commands/path.rs index e137d4b..eaac33a 100644 --- a/brood/src/commands/path.rs +++ b/brood/src/commands/path.rs @@ -2,32 +2,67 @@ use std::fs::File; use std::io::{self, BufReader}; use std::path::Path; -use crate::data::AdjacencyList; +use crate::data::{AdjacencyList, Page, PageInfo}; use crate::util; +fn find_index_of_title(pages: &[Page], title: &str) -> u32 { + let title = util::normalize_link(title); + 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 +} + +struct DijkstraPageInfo { + distance: u32, + prev_page_idx: u32, +} + +impl Default for DijkstraPageInfo { + fn default() -> Self { + Self { + distance: u32::MAX, + prev_page_idx: u32::MAX, + } + } +} + +fn dijkstra( + mut data: AdjacencyList, + from_idx: u32, + to_idx: u32, +) -> Option> { + todo!() +} + pub fn path(datafile: &Path, from: &str, to: &str) -> io::Result<()> { - eprintln!(">> Import"); + println!(">> Import"); let mut databuf = BufReader::new(File::open(datafile)?); let data = AdjacencyList::read(&mut databuf)?; + let pages = data.pages.clone(); + let data = data + .change_page_data(&|_| DijkstraPageInfo::default()) + .change_link_data(&|_| ()); - eprintln!(">> Locate from and to"); - let from = util::normalize_link(from); - let to = util::normalize_link(to); - let (from_i, from_p) = data - .pages - .iter() - .enumerate() - .filter(|(_, p)| !p.data.redirect) - .find(|(_, p)| util::normalize_link(&p.data.title) == from) - .unwrap_or_else(|| panic!("no article called {from}")); - let (to_i, to_p) = data - .pages - .iter() - .enumerate() - .filter(|(_, p)| !p.data.redirect) - .find(|(_, p)| util::normalize_link(&p.data.title) == to) - .unwrap_or_else(|| panic!("no article called {to}")); - dbg!(from_i, from_p, to_i, to_p); + println!(">> Locate from and to"); + let from_idx = find_index_of_title(&pages, from); + let to_idx = find_index_of_title(&pages, to); + + println!(">> Find path"); + let path = dijkstra(data, from_idx, to_idx); + + if let Some(path) = path { + println!("Path found:"); + for page_idx in path { + let page = &pages[page_idx as usize]; + println!(" - {}", page.data.title); + } + } else { + println!("No path found"); + } Ok(()) } diff --git a/brood/src/data.rs b/brood/src/data.rs index 0520d54..91d8db5 100644 --- a/brood/src/data.rs +++ b/brood/src/data.rs @@ -217,7 +217,7 @@ impl AdjacencyList { } impl AdjacencyList { - pub fn change_page_data(self, page_f: &impl Fn(P) -> P2) -> AdjacencyList { + pub fn change_page_data(self, page_f: &impl Fn(P) -> P2) -> AdjacencyList { let pages = self .pages .into_iter() @@ -230,7 +230,7 @@ impl AdjacencyList { } } - pub fn change_link_data(self, link_f: &impl Fn(L) -> L2) -> AdjacencyList { + pub fn change_link_data(self, link_f: &impl Fn(L) -> L2) -> AdjacencyList { let links = self .links .into_iter()