91 lines
2.3 KiB
Rust
91 lines
2.3 KiB
Rust
use super::bingo::{Board, Field, Game};
|
|
use crate::parsing::{newline, parse_number, space};
|
|
use yap::{IntoTokens, Tokens};
|
|
|
|
pub fn parse_field(tokens: &mut impl Tokens<Item = char>) -> Option<Field> {
|
|
parse_number(tokens).map(|number| Field {
|
|
number,
|
|
marked: false,
|
|
})
|
|
}
|
|
|
|
pub fn parse_field_line(tokens: &mut impl Tokens<Item = char>) -> Option<[Field; 5]> {
|
|
tokens
|
|
.sep_by(|t| parse_field(t), |t| space(t))
|
|
.collect::<Vec<Field>>()
|
|
.try_into()
|
|
.ok()
|
|
}
|
|
|
|
pub fn parse_field_line_array(tokens: &mut impl Tokens<Item = char>) -> Option<[[Field; 5]; 5]> {
|
|
tokens
|
|
.sep_by(|t| parse_field_line(t), |t| newline(t))
|
|
.collect::<Vec<[Field; 5]>>()
|
|
.try_into()
|
|
.ok()
|
|
}
|
|
|
|
pub fn parse_board(tokens: &mut impl Tokens<Item = char>) -> Option<Board> {
|
|
parse_field_line_array(tokens).map(|fields| Board {
|
|
fields,
|
|
finished: false,
|
|
})
|
|
}
|
|
|
|
pub fn parse_boards(tokens: &mut impl Tokens<Item = char>) -> Vec<Board> {
|
|
tokens
|
|
.sep_by(|t| parse_board(t), |t| newline(t) && newline(t))
|
|
.collect()
|
|
}
|
|
|
|
pub fn parse_input_numbers(tokens: &mut impl Tokens<Item = char>) -> Vec<usize> {
|
|
tokens
|
|
.sep_by(|t| parse_number(t), |t| t.token(','))
|
|
.collect()
|
|
}
|
|
|
|
pub fn parse_game(input: &str) -> Game {
|
|
let mut tokens = input.into_tokens();
|
|
let input_numbers = parse_input_numbers(&mut tokens);
|
|
tokens.skip_many(newline);
|
|
let boards = parse_boards(&mut tokens);
|
|
Game {
|
|
input_numbers,
|
|
boards,
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use yap::IntoTokens;
|
|
|
|
#[test]
|
|
fn parse_input_numbers() {
|
|
assert_eq!(
|
|
vec![1, 2, 3],
|
|
super::parse_input_numbers(&mut "1,2,3".into_tokens())
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn parse_field_line() {
|
|
if let Some(line) = super::parse_field_line(&mut " 3 15 0 2 22".into_tokens()) {
|
|
assert_eq!(3, line[0].number);
|
|
assert_eq!(15, line[1].number);
|
|
assert_eq!(0, line[2].number);
|
|
assert_eq!(2, line[3].number);
|
|
assert_eq!(22, line[4].number);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn parse_board() {
|
|
const BOARD: &str = " 3 15 0 2 22
|
|
9 18 13 17 5
|
|
19 8 7 25 23
|
|
20 11 10 24 4
|
|
14 21 16 12 6";
|
|
assert!(super::parse_board(&mut BOARD.into_tokens()).is_some());
|
|
}
|
|
}
|