diff --git a/src/lib.rs b/src/lib.rs index 207da44..14f0961 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #[doc = include_str!("../README.md")] pub mod wikipedia_infobox_analyzer { - use ascii_table::{Align, AsciiTable}; use regex::Regex; use itertools::Itertools; @@ -20,43 +19,20 @@ pub mod wikipedia_infobox_analyzer { .collect() } - /// Creates an ascii infobox out of the properties - pub fn format_infobox_from_used_properties(name: String, qid: String, properties_template: Vec, properties_item: Vec, ) -> String { - let mut ascii_table = AsciiTable::default(); - ascii_table.set_max_width(80); - ascii_table - .column(0) - .set_header("Infobox requires") - .set_align(Align::Left); - - ascii_table - .column(1) - .set_header(format!("Wikidata {name} ({qid})")) - .set_align(Align::Left); - - // Display the property columns as a table - let data: Vec> = join_columns(&properties_template, &properties_item) - .iter() - .map(|&m| { - let (v1, v2) = m; - vec![ v1.map_or("".to_owned(), |v| format!("P{v}").to_owned()) - , v2.map_or("".to_owned(), |v| format!("P{v}").to_owned())] - } - ).collect(); - ascii_table.format(data) - } - /// Properties will be displayed in the right column if they are in the list for that column + /// /// All items in the left columns will be displayed /// The remaining items in the right columns not in the left columns will trail in the right column + /// ``` /// ┌───────┬───────┐ /// │ 1 │ 1 │ /// │ 3 │ │ /// │ │ 2 │ /// │ │ 4 │ /// └───────┴───────┘ + /// ``` /// So for example, [1, 3] and [1, 2, 4] become [1, 2, 3, 4], as shown above - fn join_columns(vec1: &[T], vec2: &[T]) -> Vec<(Option, Option)> { + pub fn join_columns(vec1: &[T], vec2: &[T]) -> Vec<(Option, Option)> { vec1.iter() .flat_map(|n1| { if let Some(&n2) = vec2.iter().find(|&x| x == n1) { @@ -124,7 +100,7 @@ pub mod wikipedia_infobox_analyzer { .collect::>() } - /// Fetch the wikidata identifier associated with the wikipedia article + /// Fetches the wikidata identifier associated with the wikipedia article pub fn fetch_wiki_item_by_article_title(title: String, language_code: String) -> u64 { let uri = format!("https://{}.wikipedia.org/w/api.php?action=query&prop=pageprops&format=json&titles={}", &language_code, &title); @@ -172,31 +148,6 @@ mod tests_lib { ); } - #[test] - fn test_format_infobox_from_used_properties() { - assert_eq!( - format_infobox_from_used_properties( - "Earth".to_string(), - "Q2".to_string(), - vec![18, 170, 571], - vec![18, 31, 138, 170, 361, 571] - ), - - concat![ - "┌──────────────────┬─────────────────────┐\n", - "│ Infobox requires │ Wikidata Earth (Q2) │\n", - "├──────────────────┼─────────────────────┤\n", - "│ P18 │ P18 │\n", // property: image - "│ P170 │ P170 │\n", // property: creator - "│ P571 │ P571 │\n", // property: inception - "│ │ P31 │\n", // property: instance of - "│ │ P138 │\n", // property: inception - "│ │ P361 │\n", // property: part of - "└──────────────────┴─────────────────────┘\n", - ] - ); - } - #[tokio::test] async fn test_fetch_name_for_wiki_property() { let name = fetch_name_for_wiki_property(31).await; diff --git a/src/main.rs b/src/main.rs index 1362bb3..7a8f5e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use wikipedia_infobox_analyzer::wikipedia_infobox_analyzer::*; +use ascii_table::{Align, AsciiTable}; use dirs_next::cache_dir; use std::collections::HashMap; use std::fs; @@ -112,6 +113,31 @@ impl Cache { } } +/// Creates an ascii table out of the properties +fn format_property_usage(name: String, qid: String, properties_template: Vec, properties_item: Vec, ) -> String { + let mut ascii_table = AsciiTable::default(); + ascii_table.set_max_width(80); + ascii_table + .column(0) + .set_header("Infobox requires") + .set_align(Align::Left); + + ascii_table + .column(1) + .set_header(format!("Wikidata {name} ({qid})")) + .set_align(Align::Left); + + // Display the property columns as a table + let data: Vec> = join_columns(&properties_template, &properties_item) + .iter() + .map(|&m| { + let (v1, v2) = m; + vec![ v1.map_or("".to_owned(), |v| format!("P{v}").to_owned()) + , v2.map_or("".to_owned(), |v| format!("P{v}").to_owned())] + } + ).collect(); + ascii_table.format(data) +} #[tokio::main] async fn main() -> Result<(), Box> { @@ -129,7 +155,7 @@ async fn main() -> Result<(), Box> { let properties_template = extract_used_properties_from_template(template); let properties_item = fetch_properties_for_wiki_item(qid); - let table = format_infobox_from_used_properties( + let table = format_property_usage( title.clone(), format!("Q{qid}"), properties_template, @@ -168,4 +194,29 @@ mod tests_main { // Cleanup let _ = cache_new.delete(); } + + #[test] + fn test_format_property_usage() { + assert_eq!( + format_property_usage( + "Earth".to_string(), + "Q2".to_string(), + vec![18, 170, 571], + vec![18, 31, 138, 170, 361, 571] + ), + + concat![ + "┌──────────────────┬─────────────────────┐\n", + "│ Infobox requires │ Wikidata Earth (Q2) │\n", + "├──────────────────┼─────────────────────┤\n", + "│ P18 │ P18 │\n", // property: image + "│ P170 │ P170 │\n", // property: creator + "│ P571 │ P571 │\n", // property: inception + "│ │ P31 │\n", // property: instance of + "│ │ P138 │\n", // property: inception + "│ │ P361 │\n", // property: part of + "└──────────────────┴─────────────────────┘\n", + ] + ); + } }