use winnow::{stream::AsChar, token::take_while, ModalResult, Parser};
use super::primitive::s;
const GNU_MAX_YEAR: u32 = 2_147_485_547;
pub(super) fn year_from_str(year_str: &str) -> Result<u32, &'static str> {
let mut year = year_str
.parse::<u32>()
.map_err(|_| "year must be a non-negative integer")?;
if year_str.len() == 2 {
if year <= 68 {
year += 2000
} else {
year += 1900
}
}
if year > GNU_MAX_YEAR {
return Err("year exceeds GNU maximum");
}
Ok(year)
}
pub(super) fn year_str<'a>(input: &mut &'a str) -> ModalResult<&'a str> {
s(take_while(1.., AsChar::is_dec_digit)).parse_next(input)
}
#[cfg(test)]
mod tests {
use super::year_from_str;
#[test]
fn test_year() {
assert_eq!(year_from_str("10").unwrap(), 2010u32);
assert_eq!(year_from_str("68").unwrap(), 2068u32);
assert_eq!(year_from_str("69").unwrap(), 1969u32);
assert_eq!(year_from_str("99").unwrap(), 1999u32);
assert_eq!(year_from_str("468").unwrap(), 468u32);
assert_eq!(year_from_str("469").unwrap(), 469u32);
assert_eq!(year_from_str("1568").unwrap(), 1568u32);
assert_eq!(year_from_str("1569").unwrap(), 1569u32);
assert_eq!(year_from_str("10000").unwrap(), 10000u32);
assert_eq!(year_from_str("2147485547").unwrap(), 2_147_485_547u32);
assert_eq!(
year_from_str("2147485548").unwrap_err(),
"year exceeds GNU maximum"
);
}
#[test]
fn test_year_errors() {
assert_eq!(
year_from_str("not-a-year").unwrap_err(),
"year must be a non-negative integer"
);
}
}