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

3 years ago
use std::io::BufRead;
3 years ago
use super::bag;
3 years ago
fn parse_rule(from: impl AsRef<str>) -> Option<bag::Rule>
3 years ago
{
3 years ago
let from = from.as_ref();
let mut ps = from.split("bag");
3 years ago
3 years ago
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(),
3 years ago
};
3 years ago
(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())
3 years ago
};
3 years ago
if n < 1 {
None
} else {
Some((n, s.to_owned()))
3 years ago
}
3 years ago
})))
}
3 years ago
3 years ago
pub fn parse<R: BufRead>(buf: R) -> impl Iterator<Item = bag::Rule>
{
buf.lines().filter_map(|x| {
x.ok().map(parse_rule).flatten()
})
3 years ago
}