use super::super::Token;
use crate::{Pattern, Quantifier, Reluctance, Result};
pub(crate) fn parse_quantifier(
pattern: Pattern,
lexer: &mut logos::Lexer<Token>,
force_repeat: bool,
) -> Result<Pattern> {
let mut lookahead = lexer.clone();
match lookahead.next() {
Some(Ok(tok)) => match tok {
Token::RepeatZeroOrMore => {
lexer.next(); Ok(Pattern::repeat(
pattern,
Quantifier::new(0.., Reluctance::Greedy),
))
}
Token::RepeatZeroOrMoreLazy => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(0.., Reluctance::Lazy),
))
}
Token::RepeatZeroOrMorePossessive => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(0.., Reluctance::Possessive),
))
}
Token::RepeatOneOrMore => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(1.., Reluctance::Greedy),
))
}
Token::RepeatOneOrMoreLazy => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(1.., Reluctance::Lazy),
))
}
Token::RepeatOneOrMorePossessive => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(1.., Reluctance::Possessive),
))
}
Token::RepeatZeroOrOne => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(0..=1, Reluctance::Greedy),
))
}
Token::RepeatZeroOrOneLazy => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(0..=1, Reluctance::Lazy),
))
}
Token::RepeatZeroOrOnePossessive => {
lexer.next();
Ok(Pattern::repeat(
pattern,
Quantifier::new(0..=1, Reluctance::Possessive),
))
}
Token::Range(res) => {
lexer.next(); let q = res?;
let pat = if let Some(max) = q.max() {
Pattern::repeat(
pattern,
Quantifier::new(q.min()..=max, q.reluctance()),
)
} else {
Pattern::repeat(
pattern,
Quantifier::new(q.min().., q.reluctance()),
)
};
Ok(pat)
}
_ => {
if force_repeat {
Ok(Pattern::repeat(pattern, Quantifier::default()))
} else {
Ok(pattern)
}
}
},
_ => {
if force_repeat {
Ok(Pattern::repeat(pattern, Quantifier::default()))
} else {
Ok(pattern)
}
}
}
}
#[cfg(test)]
mod tests {
use logos::Logos;
use super::*;
#[test]
fn test_parse_quantifier_star() {
let mut lexer = Token::lexer("*");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42)*");
}
#[test]
fn test_parse_quantifier_plus() {
let mut lexer = Token::lexer("+");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42)+");
}
#[test]
fn test_parse_quantifier_question() {
let mut lexer = Token::lexer("?");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42)?");
}
#[test]
fn test_parse_quantifier_lazy() {
let mut lexer = Token::lexer("*?");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42)*?");
}
#[test]
fn test_parse_quantifier_possessive() {
let mut lexer = Token::lexer("++");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42)++");
}
#[test]
fn test_parse_quantifier_range() {
let mut lexer = Token::lexer("{3,5}");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "(42){3,5}");
}
#[test]
fn test_parse_quantifier_no_quantifier() {
let mut lexer = Token::lexer("OTHER");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, false).unwrap();
assert_eq!(result.to_string(), "42");
}
#[test]
fn test_parse_quantifier_force_repeat() {
let mut lexer = Token::lexer("OTHER");
let pattern = Pattern::number(42);
let result = parse_quantifier(pattern, &mut lexer, true).unwrap();
assert_eq!(result.to_string(), "(42){1}");
}
}