use fundu_core::config::NumbersLike;
use fundu_core::time::Multiplier;
pub(crate) mod builder;
pub(crate) mod parser;
pub(crate) mod time_units;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Numeral<'a> {
identifiers: &'a [&'a str],
multiplier: Multiplier,
}
impl<'a> Numeral<'a> {
pub fn new(identifiers: &'a [&'a str], multiplier: Multiplier) -> Self {
Self {
identifiers,
multiplier,
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct Numerals<'a> {
data: Vec<Numeral<'a>>,
}
impl<'a> Numerals<'a> {
pub(crate) fn new() -> Self {
Self { data: vec![] }
}
pub(crate) fn with_numerals(numerals: Vec<Numeral<'a>>) -> Self {
Self { data: numerals }
}
pub(crate) fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
impl<'a> NumbersLike for Numerals<'a> {
fn get(&self, input: &str) -> Option<Multiplier> {
self.data.iter().find_map(|numeral| {
numeral
.identifiers
.iter()
.find_map(|id| (*id == input).then_some(numeral.multiplier))
})
}
}
#[cfg(test)]
mod tests {
use rstest::{fixture, rstest};
use super::*;
#[fixture]
pub fn numeral_this() -> Numeral<'static> {
Numeral::new(&["this"], Multiplier(0, 0))
}
#[fixture]
pub fn numeral_last() -> Numeral<'static> {
Numeral::new(&["last"], Multiplier(-1, 0))
}
#[fixture]
pub fn numeral_next() -> Numeral<'static> {
Numeral::new(&["next"], Multiplier(1, 0))
}
#[rstest]
fn test_numeral_new(numeral_this: Numeral) {
assert_eq!(numeral_this.identifiers, &["this"]);
assert_eq!(numeral_this.multiplier, Multiplier(0, 0));
}
#[test]
fn test_numerals_new() {
let numerals = Numerals::new();
assert!(numerals.is_empty());
}
#[rstest]
#[case::last("last", Multiplier(-1, 0))]
#[case::this("this", Multiplier(0, 0))]
#[case::next("next", Multiplier(1, 0))]
fn test_numerals_with_valid_numerals(
#[case] input: &str,
#[case] expected: Multiplier,
numeral_this: Numeral,
numeral_last: Numeral,
numeral_next: Numeral,
) {
let numerals = Numerals::with_numerals(vec![numeral_last, numeral_this, numeral_next]);
assert!(!numerals.is_empty());
assert_eq!(numerals.get(input), Some(expected));
}
#[rstest]
#[case::empty("")]
#[case::incomplete("las")]
#[case::too_much("lasts")]
#[case::capitalized("Last")]
#[case::upper_case("LAST")]
fn test_numerals_with_invalid_numerals(#[case] input: &str, numeral_last: Numeral) {
let numerals = Numerals::with_numerals(vec![numeral_last]);
assert_eq!(numerals.get(input), None);
}
}