rustgym 0.2.0

rustgym solutions
Documentation
struct Solution;
use std::collections::HashSet;
use std::iter::FromIterator;
use std::iter::Peekable;
use std::str::Chars;
use std::vec::IntoIter;

#[derive(Debug)]
enum Tok {
    S(String),
    Op(char),
}

impl Solution {
    fn brace_expansion_ii(expression: String) -> Vec<String> {
        let mut it = expression.chars().peekable();
        let toks = Self::parse_tokens(&mut it);
        let mut it = toks.into_iter().peekable();
        let mut sorted: Vec<String> = Self::parse(&mut it).into_iter().collect();
        sorted.sort_unstable();
        sorted
    }

    fn concat(a: &HashSet<String>, b: &HashSet<String>) -> HashSet<String> {
        let mut res = HashSet::new();
        for i in a {
            for j in b {
                res.insert(format!("{}{}", i, j));
            }
        }
        res
    }

    fn parse(it: &mut Peekable<IntoIter<Tok>>) -> HashSet<String> {
        let mut res = HashSet::from_iter(vec!["".to_string()]);
        while it.len() != 0 {
            if Self::eat(it, '{') {
                res = Self::concat(&res, &Self::parse(it));
                Self::eat(it, '}');
                continue;
            }
            if Self::eat(it, ',') {
                res = &res | &Self::parse(it);
                continue;
            }
            if let Some(Tok::Op('}')) = it.peek() {
                break;
            }
            if let Some(Tok::S(s)) = it.next() {
                res = Self::concat(&res, &HashSet::from_iter(vec![s]));
                continue;
            }
        }
        res
    }

    fn eat(it: &mut Peekable<IntoIter<Tok>>, c: char) -> bool {
        if let Some(&Tok::Op(t)) = it.peek() {
            if t == c {
                it.next();
                true
            } else {
                false
            }
        } else {
            false
        }
    }

    fn parse_tokens(it: &mut Peekable<Chars>) -> Vec<Tok> {
        let mut res = vec![];
        while let Some(c) = it.next() {
            match c {
                '{' | '}' | ',' => res.push(Tok::Op(c)),
                'a'..='z' => {
                    let mut s = "".to_string();
                    s.push(c);
                    while let Some('a'..='z') = it.peek() {
                        s.push(it.next().unwrap());
                    }
                    res.push(Tok::S(s));
                }
                _ => {}
            }
        }
        res
    }
}

#[test]
fn test() {
    let expression = "{a,b}{c,{d,e}}".to_string();
    let res = vec_string!["ac", "ad", "ae", "bc", "bd", "be"];
    assert_eq!(Solution::brace_expansion_ii(expression), res);
    let expression = "{{a,z},a{b,c},{ab,z}}".to_string();
    let res = vec_string!["a", "ab", "ac", "z"];
    assert_eq!(Solution::brace_expansion_ii(expression), res);
}