add single digit parser

This commit is contained in:
Jan Christian Grünhage 2021-12-10 08:14:16 +01:00
parent 52929d9a95
commit e02dbc3577

View file

@ -9,18 +9,43 @@ pub fn newline(tokens: &mut impl Tokens<Item = char>) -> bool {
} }
pub fn parse_number<T: Num>(tokens: &mut impl Tokens<Item = char>) -> Option<T> { pub fn parse_number<T: Num>(tokens: &mut impl Tokens<Item = char>) -> Option<T> {
parse_number_with_radix(tokens, 10) parse_number_with_radix(tokens, 10, None)
}
pub fn parse_digit<T: Num>(tokens: &mut impl Tokens<Item = char>) -> Option<T> {
parse_number_with_radix(tokens, 10, Some(1))
} }
pub fn parse_number_with_radix<T: Num>( pub fn parse_number_with_radix<T: Num>(
tokens: &mut impl Tokens<Item = char>, tokens: &mut impl Tokens<Item = char>,
base: u32, base: u32,
limit: Option<usize>,
) -> Option<T> { ) -> Option<T> {
tokens.skip_tokens_while(|t| *t == ' '); tokens.skip_tokens_while(|t| *t == ' ');
let digits: String = tokens.tokens_while(|c| c.is_digit(base)).collect(); let mut remaining = limit.map(|x| x as isize).unwrap_or(isize::MAX);
let digits: String = tokens
.tokens_while(|c| {
remaining -= 1;
c.is_digit(base) && remaining >= 0
})
.collect();
if !digits.is_empty() { if !digits.is_empty() {
T::from_str_radix(&digits, base).ok() T::from_str_radix(&digits, base).ok()
} else { } else {
None None
} }
} }
#[cfg(test)]
mod test {
use yap::IntoTokens;
#[test]
fn parse_digit() {
let mut tokens = "1234".into_tokens();
assert_eq!(Some(1), super::parse_digit(&mut tokens));
assert_eq!(Some(2), super::parse_digit(&mut tokens));
assert_eq!(Some(3), super::parse_digit(&mut tokens));
assert_eq!(Some(4), super::parse_digit(&mut tokens));
}
}