use clap::{Arg, ArgMatches, Command};
pub fn command() -> Command {
Command::new("match")
.about("Match a string to an identifier")
.long_about(
"Match a string to an identifier. Supports affiliation matching for ROR.\n\n\
Example usage:\n\n\
commonmeta match \"Leibniz Universität Hannover\"",
)
.arg(
Arg::new("input")
.help("The string to match, e.g. an affiliation name")
.required(true)
.index(1),
)
.arg(
Arg::new("from")
.long("from")
.short('f')
.help("Input format to match against (currently only 'ror' is supported)")
.default_value("ror"),
)
.arg(
Arg::new("to")
.long("to")
.short('t')
.help("Output format: ror (raw ROR JSON) or inveniordm (vocabulary YAML)")
.default_value("ror"),
)
}
pub fn execute(matches: &ArgMatches) -> Result<(), String> {
let input = matches.get_one::<String>("input").expect("required");
let from = matches.get_one::<String>("from").map(String::as_str).unwrap_or("ror");
let to = matches.get_one::<String>("to").map(String::as_str).unwrap_or("ror");
let to = if to.is_empty() || to == "commonmeta" { "ror" } else { to };
if from != "ror" {
println!("No valid input format. Currently only 'ror' is supported.");
return Ok(());
}
let candidates = commonmeta::match_ror_affiliation(input).map_err(|e| e.to_string())?;
let chosen = candidates.into_iter().find(|m| m.chosen);
let organization = match chosen {
Some(m) => m.organization,
None => {
println!("No match found");
return Ok(());
}
};
let output = match to {
"inveniordm" => commonmeta::write("ror", &organization).map_err(|e| e.to_string())?,
"ror" => commonmeta::write_ror_json(&organization).map_err(|e| e.to_string())?,
other => return Err(format!("match: unsupported --to format: {}", other)),
};
println!("{}", String::from_utf8_lossy(&output));
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_command_defaults() {
let matches = command().get_matches_from(vec!["match", "Leibniz Universität Hannover"]);
assert_eq!(matches.get_one::<String>("from").map(String::as_str), Some("ror"));
assert_eq!(matches.get_one::<String>("to").map(String::as_str), Some("ror"));
assert_eq!(
matches.get_one::<String>("input").map(String::as_str),
Some("Leibniz Universität Hannover")
);
}
#[test]
fn test_unsupported_from_returns_message_not_error() {
let matches =
command().get_matches_from(vec!["match", "some affiliation", "--from", "grid"]);
let result = execute(&matches);
assert!(result.is_ok());
}
}