43 lines
1.1 KiB
Rust
43 lines
1.1 KiB
Rust
|
use yap::Tokens;
|
||
|
|
||
|
use crate::parsing::{parse_n, parse_number};
|
||
|
|
||
|
use super::model::TargetArea;
|
||
|
|
||
|
pub fn parse_target_area(tokens: &mut impl Tokens<Item = char>) -> Option<TargetArea> {
|
||
|
tokens.optional(|t| {
|
||
|
if !t.tokens("target area: x=".chars()) {
|
||
|
return None;
|
||
|
}
|
||
|
let x = parse_bounds(t)?;
|
||
|
if !t.tokens(", y=".chars()) {
|
||
|
return None;
|
||
|
}
|
||
|
let y = parse_bounds(t)?;
|
||
|
Some(TargetArea(x, y))
|
||
|
})
|
||
|
}
|
||
|
|
||
|
pub fn parse_bounds(tokens: &mut impl Tokens<Item = char>) -> Option<(isize, isize)> {
|
||
|
tokens.optional(|t| {
|
||
|
let numbers: Option<[isize; 2]> =
|
||
|
parse_n(t, |t| parse_number(t), |t| t.tokens("..".chars()));
|
||
|
numbers.map(|numbers| (numbers[0], numbers[1]))
|
||
|
})
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod test {
|
||
|
use yap::IntoTokens;
|
||
|
|
||
|
use crate::day_17::model::TargetArea;
|
||
|
|
||
|
const EXAMPLE: &str = "target area: x=20..30, y=-10..-5";
|
||
|
|
||
|
#[test]
|
||
|
fn parse_example() {
|
||
|
let example = super::parse_target_area(&mut EXAMPLE.into_tokens());
|
||
|
assert_eq!(example, Some(TargetArea((20, 30), (-10, -5))));
|
||
|
}
|
||
|
}
|