73 lines
2.1 KiB
Rust
73 lines
2.1 KiB
Rust
use yap::Tokens;
|
|
|
|
use crate::parsing::{newline, parse_n};
|
|
|
|
use super::{Cave, CaveSystem};
|
|
|
|
pub fn parse_cave_system(tokens: &mut impl Tokens<Item = char>) -> Option<CaveSystem> {
|
|
let edges = tokens.sep_by(|t| parse_edge(t), |t| newline(t)).collect();
|
|
CaveSystem::new(edges).ok()
|
|
}
|
|
|
|
pub fn parse_edge(tokens: &mut impl Tokens<Item = char>) -> Option<[Cave; 2]> {
|
|
parse_n(tokens, |t| parse_cave(t), |t| t.token('-'))
|
|
}
|
|
|
|
pub fn parse_cave(tokens: &mut impl Tokens<Item = char>) -> Option<Cave> {
|
|
yap::one_of!(ts from tokens;
|
|
parse_start(ts),
|
|
parse_end(ts),
|
|
parse_big(ts),
|
|
parse_small(ts),
|
|
)
|
|
}
|
|
|
|
pub fn parse_start(tokens: &mut impl Tokens<Item = char>) -> Option<Cave> {
|
|
tokens.tokens("start".chars()).then(|| Cave::Start)
|
|
}
|
|
|
|
pub fn parse_end(tokens: &mut impl Tokens<Item = char>) -> Option<Cave> {
|
|
tokens.tokens("end".chars()).then(|| Cave::End)
|
|
}
|
|
|
|
pub fn parse_big(tokens: &mut impl Tokens<Item = char>) -> Option<Cave> {
|
|
let cave: String = tokens.tokens_while(|c| c.is_ascii_uppercase()).collect();
|
|
(!cave.is_empty()).then(|| Cave::Big(cave))
|
|
}
|
|
|
|
pub fn parse_small(tokens: &mut impl Tokens<Item = char>) -> Option<Cave> {
|
|
let cave: String = tokens.tokens_while(|c| c.is_ascii_lowercase()).collect();
|
|
(!cave.is_empty()).then(|| Cave::Small(cave))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use yap::IntoTokens;
|
|
|
|
use super::super::Cave;
|
|
|
|
#[test]
|
|
fn parse_cave() {
|
|
assert_eq!(
|
|
super::parse_cave(&mut "start".into_tokens()),
|
|
Some(Cave::Start)
|
|
);
|
|
assert_eq!(super::parse_cave(&mut "end".into_tokens()), Some(Cave::End));
|
|
assert_eq!(
|
|
super::parse_cave(&mut "a".into_tokens()),
|
|
Some(Cave::Small(String::from("a")))
|
|
);
|
|
assert_eq!(
|
|
super::parse_cave(&mut "BBBB".into_tokens()),
|
|
Some(Cave::Big(String::from("BBBB")))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_edge() {
|
|
assert!(super::parse_edge(&mut "start-DX".into_tokens()).is_some());
|
|
assert!(super::parse_edge(&mut "a-DX".into_tokens()).is_some());
|
|
assert!(super::parse_edge(&mut "AAA-b".into_tokens()).is_some());
|
|
}
|
|
}
|