Move table formatting function to main

Raymon Zutekouw 3 weeks ago
parent bd14c26285
commit 3c1fd68229
Signed by: raymon
GPG Key ID: 0E62222846283925
  1. 57
      src/lib.rs
  2. 53
      src/main.rs

@ -1,6 +1,5 @@
#[doc = include_str!("../README.md")] #[doc = include_str!("../README.md")]
pub mod wikipedia_infobox_analyzer { pub mod wikipedia_infobox_analyzer {
use ascii_table::{Align, AsciiTable};
use regex::Regex; use regex::Regex;
use itertools::Itertools; use itertools::Itertools;
@ -20,43 +19,20 @@ pub mod wikipedia_infobox_analyzer {
.collect() .collect()
} }
/// Creates an ascii infobox out of the properties
pub fn format_infobox_from_used_properties(name: String, qid: String, properties_template: Vec<u64>, properties_item: Vec<u64>, ) -> 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<Vec<String>> = 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 /// 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 /// 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 /// The remaining items in the right columns not in the left columns will trail in the right column
/// ```
/// ┌───────┬───────┐ /// ┌───────┬───────┐
/// │ 1 │ 1 │ /// │ 1 │ 1 │
/// │ 3 │ │ /// │ 3 │ │
/// │ │ 2 │ /// │ │ 2 │
/// │ │ 4 │ /// │ │ 4 │
/// └───────┴───────┘ /// └───────┴───────┘
/// ```
/// So for example, [1, 3] and [1, 2, 4] become [1, 2, 3, 4], as shown above /// So for example, [1, 3] and [1, 2, 4] become [1, 2, 3, 4], as shown above
fn join_columns<T: Copy + Eq>(vec1: &[T], vec2: &[T]) -> Vec<(Option<T>, Option<T>)> { pub fn join_columns<T: Copy + Eq>(vec1: &[T], vec2: &[T]) -> Vec<(Option<T>, Option<T>)> {
vec1.iter() vec1.iter()
.flat_map(|n1| { .flat_map(|n1| {
if let Some(&n2) = vec2.iter().find(|&x| x == n1) { if let Some(&n2) = vec2.iter().find(|&x| x == n1) {
@ -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] #[tokio::test]
async fn test_fetch_name_for_wiki_property() { async fn test_fetch_name_for_wiki_property() {
let name = fetch_name_for_wiki_property(31).await; let name = fetch_name_for_wiki_property(31).await;

@ -1,5 +1,6 @@
use wikipedia_infobox_analyzer::wikipedia_infobox_analyzer::*; use wikipedia_infobox_analyzer::wikipedia_infobox_analyzer::*;
use ascii_table::{Align, AsciiTable};
use dirs_next::cache_dir; use dirs_next::cache_dir;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; 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<u64>, properties_item: Vec<u64>, ) -> 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<Vec<String>> = 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] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -129,7 +155,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let properties_template = extract_used_properties_from_template(template); let properties_template = extract_used_properties_from_template(template);
let properties_item = fetch_properties_for_wiki_item(qid); let properties_item = fetch_properties_for_wiki_item(qid);
let table = format_infobox_from_used_properties( let table = format_property_usage(
title.clone(), title.clone(),
format!("Q{qid}"), format!("Q{qid}"),
properties_template, properties_template,
@ -168,4 +194,29 @@ mod tests_main {
// Cleanup // Cleanup
let _ = cache_new.delete(); 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",
]
);
}
} }

Loading…
Cancel
Save