You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.1 KiB

use std::io::BufRead;
use super::bag;
fn parse_rule(from: impl AsRef<str>) -> Option<bag::Rule>
{
let from = from.as_ref();
let mut ps = from.split("bag");
let name = ps.next()?.trim();
Some(bag::Rule::new(name, (0..).zip(ps).filter_map(|(i, s)| {
let (n, s) = if i == 0 {
const JUNK: &str = "s contain ";
let (spec, rest) = (&s[JUNK.len()..]).split_once(char::is_whitespace).unwrap();
let n: usize = match spec {
"no" => 0,
x => x.parse().unwrap(),
};
(n, rest.trim())
} else {
if s.contains(".") { return None; }
let s = if s.starts_with("s") {
&s[3..]
} else if s.starts_with(",") {
&s[2..]
} else {
s
}.trim();
//if s.starts_with(".") { return None; }
let (spec, rest) = s.split_once(char::is_whitespace).unwrap();
(spec.parse().unwrap(), rest.trim())
};
if n < 1 {
None
} else {
Some((n, s.to_owned()))
}
})))
}
pub fn parse<R: BufRead>(buf: R) -> impl Iterator<Item = bag::Rule>
{
buf.lines().filter_map(|x| {
x.ok().map(parse_rule).flatten()
})
}