use super::Token;
pub fn match_from(tokens: &[Token], input: &[u8], start: usize) -> Option<usize> {
let mut positions = vec![start];
for (token_index, token) in tokens.iter().enumerate() {
let last_token = token_index + 1 == tokens.len();
let mut next_positions = Vec::new();
for pos in positions {
match *token {
Token::Literal(byte) if input.get(pos).is_some_and(|&value| value == byte) => {
next_positions.push(pos + 1);
}
Token::Any if pos < input.len() => next_positions.push(pos + 1),
Token::StarLiteral(byte) => {
let mut end = pos;
next_positions.push(end);
while input.get(end).is_some_and(|&value| value == byte) {
end += 1;
next_positions.push(end);
}
}
Token::StarAny => {
if last_token {
next_positions.push(input.len());
} else {
next_positions.extend(pos..=input.len());
}
}
_ => {}
}
}
next_positions.sort_unstable();
next_positions.dedup();
if next_positions.is_empty() {
return None;
}
positions = next_positions;
}
positions.into_iter().min()
}