pub struct LexiconSchema;
impl LexiconSchema {
pub fn get_arity(word: &str) -> Option<usize> {
nibli_lexicon::get_arity(word)
}
pub fn get_arity_or_default(word: &str) -> usize {
Self::get_arity(word).unwrap_or(2)
}
pub fn injected_arity(relation: &str, provided: usize) -> Result<usize, String> {
match Self::get_arity(relation) {
Some(a) if provided > a => Err(format!(
"{relation:?} has arity {a}, but {provided} arguments were supplied — \
refusing to silently drop the extras"
)),
Some(a) => Ok(a),
None => Ok(provided),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_arity_known_alias_goes() {
let arity = LexiconSchema::get_arity("goes");
assert!(arity.is_some());
assert_eq!(arity.unwrap(), 5);
}
#[test]
fn test_get_arity_known_alias_dog() {
let arity = LexiconSchema::get_arity("dog");
assert!(arity.is_some());
assert_eq!(arity.unwrap(), 2);
}
#[test]
fn test_get_arity_known_alias_loves() {
let arity = LexiconSchema::get_arity("loves");
assert!(arity.is_some());
assert_eq!(arity.unwrap(), 2);
}
#[test]
fn test_get_arity_known_alias_talks() {
let arity = LexiconSchema::get_arity("talks");
assert!(arity.is_some());
assert_eq!(arity.unwrap(), 4);
}
#[test]
fn test_gismu_never_resolves() {
assert_eq!(LexiconSchema::get_arity("klama"), None);
assert_eq!(LexiconSchema::get_arity("gerku"), None);
}
#[test]
fn test_get_arity_unknown_word_returns_none() {
assert_eq!(LexiconSchema::get_arity("zzzzz"), None);
}
#[test]
fn test_get_arity_empty_string_returns_none() {
assert_eq!(LexiconSchema::get_arity(""), None);
}
#[test]
fn test_get_arity_cmavo_not_in_dict() {
assert_eq!(LexiconSchema::get_arity("lo"), None);
assert_eq!(LexiconSchema::get_arity("cu"), None);
}
#[test]
fn test_get_arity_or_default_known_alias() {
assert_eq!(LexiconSchema::get_arity_or_default("goes"), 5);
}
#[test]
fn test_get_arity_or_default_unknown_returns_two() {
assert_eq!(LexiconSchema::get_arity_or_default("xyzzy"), 2);
}
#[test]
fn test_get_arity_or_default_empty_returns_two() {
assert_eq!(LexiconSchema::get_arity_or_default(""), 2);
}
#[test]
fn test_get_arity_english_alias() {
assert_eq!(LexiconSchema::get_arity("goes"), Some(5));
assert_eq!(LexiconSchema::get_arity("dog"), Some(2));
assert_eq!(LexiconSchema::get_arity_or_default("goes"), 5);
}
#[test]
fn test_various_alias_arities() {
let checks = vec![
("cat", 2), ("big", 3), ("fast", 2), ("person", 1), ("name", 3), ("gives", 3), ("product", 3), ("sum", 3), ("quantity", 3), ];
for (word, expected) in checks {
let actual = LexiconSchema::get_arity(word);
assert!(actual.is_some(), "expected {} to resolve", word);
assert_eq!(
actual.unwrap(),
expected,
"{} should have arity {}, got {}",
word,
expected,
actual.unwrap()
);
}
}
#[test]
fn test_unknown_word_arity_is_none() {
assert_eq!(LexiconSchema::get_arity("brivla"), None);
}
#[test]
fn test_injected_arity_policy() {
assert_eq!(LexiconSchema::injected_arity("product", 3), Ok(3));
assert_eq!(LexiconSchema::injected_arity("product", 1), Ok(3));
let e = LexiconSchema::injected_arity("product", 4).unwrap_err();
assert!(e.contains("arity 3") && e.contains("4 arguments"), "{e}");
assert_eq!(LexiconSchema::injected_arity("zzz_unknown", 1), Ok(1));
assert_eq!(LexiconSchema::injected_arity("zzz_unknown", 5), Ok(5));
}
#[test]
fn test_get_arity_consistent_with_default() {
let word = "goes";
let arity = LexiconSchema::get_arity(word).unwrap();
let default_arity = LexiconSchema::get_arity_or_default(word);
assert_eq!(arity, default_arity);
}
}