1use crate::cube::*;
4use regex::Regex;
5use std::str::FromStr;
6
7fn parse_base_move(token: &str) -> Result<BaseMoveToken, strum::ParseError> {
8 BaseMoveToken::from_str(token)
9}
10
11pub fn parse_scramble(scramble: &str) -> Result<Vec<MoveInstance>, strum::ParseError> {
15 let mut parsed = vec![];
16 let re_normal = Regex::new(r"^([UDLRFB])$").unwrap();
17 let re_prime = Regex::new(r"^([UDLRFB])'").unwrap();
18 let re_double = Regex::new(r"^([UDLRFB])2").unwrap();
19 let mut parse_error = "";
20 'tokens: for token in scramble.split_whitespace() {
21 if re_normal.is_match(token) {
22 for cap in re_normal.captures_iter(token) {
23 let basemove = parse_base_move(&cap[1])?;
24 parsed.push(MoveInstance {
25 basemove,
26 dir: Direction::Normal,
27 })
28 }
29 } else if re_prime.is_match(token) {
30 for cap in re_prime.captures_iter(token) {
31 let basemove = parse_base_move(&cap[1])?;
32 parsed.push(MoveInstance {
33 basemove,
34 dir: Direction::Prime,
35 })
36 }
37 } else if re_double.is_match(token) {
38 for cap in re_double.captures_iter(token) {
39 let basemove = parse_base_move(&cap[1])?;
40 parsed.push(MoveInstance {
41 basemove,
42 dir: Direction::Double,
43 })
44 }
45 } else {
46 parse_error = token;
47 break 'tokens;
48 }
49 }
50 if parse_error.len() > 0 {
51 Err(strum::ParseError::VariantNotFound)
52 } else {
53 Ok(parsed)
54 }
55}