61 lines
1.4 KiB
Rust
61 lines
1.4 KiB
Rust
use super::model::{Line, Point};
|
|
use crate::parsing::{newline, parse_number};
|
|
use yap::{IntoTokens, Tokens};
|
|
|
|
pub fn parse_point(tokens: &mut impl Tokens<Item = char>) -> Option<Point> {
|
|
let numbers: Vec<usize> = tokens
|
|
.sep_by(|t| parse_number(t), |t| t.token(','))
|
|
.collect();
|
|
if numbers.len() == 2 {
|
|
Some(Point {
|
|
x: numbers[0],
|
|
y: numbers[1],
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn parse_line(tokens: &mut impl Tokens<Item = char>) -> Option<Line> {
|
|
let points: Vec<Point> = tokens
|
|
.sep_by(|t| parse_point(t), |t| t.tokens(" -> ".into_tokens()))
|
|
.collect();
|
|
if points.len() == 2 {
|
|
Some(Line {
|
|
start: points[0],
|
|
end: points[1],
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn parse_lines(tokens: &mut impl Tokens<Item = char>) -> Vec<Line> {
|
|
tokens.sep_by(|t| parse_line(t), |t| newline(t)).collect()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::super::model::{Line, Point};
|
|
use yap::IntoTokens;
|
|
|
|
#[test]
|
|
fn parse_point() {
|
|
assert_eq!(
|
|
Some(Point { x: 1, y: 3 }),
|
|
super::parse_point(&mut "1,3".into_tokens())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_line() {
|
|
assert_eq!(
|
|
Some(Line {
|
|
start: Point { x: 1, y: 3 },
|
|
end: Point { x: 5, y: 3 }
|
|
}),
|
|
super::parse_line(&mut "1,3 -> 5,3".into_tokens())
|
|
);
|
|
}
|
|
}
|