From a0f3a7f8ba9036d1fcb18941a54077082f15cf3c Mon Sep 17 00:00:00 2001 From: tslil clingman <> Date: Sat, 9 Jan 2021 22:42:12 -0500 Subject: Added .rustfmt.toml, tabs for indentation, spaces for alignment --- src/parser.rs | 408 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 204 insertions(+), 204 deletions(-) (limited to 'src/parser.rs') diff --git a/src/parser.rs b/src/parser.rs index abac3dc..1e3ecf4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,231 +1,231 @@ /* - This file is part of Takwrap. + This file is part of Takwrap. - Takwrap is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Takwrap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - Takwrap is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Takwrap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Takwrap. If not, see . + You should have received a copy of the GNU General Public License + along with Takwrap. If not, see . */ use crate::game::*; fn parse_move(mv: &str) -> Result { - let mut chars = mv.chars(); - - let c = chars.next(); - if c.is_none() { - return Err(String::from("Empty string cannot be parsed.")); - } - - let x; - let picked_up; - let dc = c.unwrap(); - if (dc >= 'a') && (dc <= 'h') { - // Optional drop number omitted, assume everything - x = dc; - picked_up = 1; - } else { - if (dc < '1') || ('9' < dc) { - return Err(String::from( - "Moves must begin with a digit in 1-8 indicating the stones picked up.", - )); - } - picked_up = dc.to_digit(10).unwrap() as u8; - - let c = chars.next(); - if c.is_none() { - return Err(String::from("Moves must specify a stack position.")); - } - - x = c.unwrap(); - } - - if (x < 'a') || (x > 'h') { - return Err(String::from( - "Moves must specify a valid position on the game board.", - )); - } - let x: u8 = x as u8 - 'a' as u8; - - let c = chars.next(); - if c.is_none() { - return Err(String::from("Moves must specify a stack position.")); - } - - let y = c.unwrap(); - if (y < '1') || (y > '8') { - return Err(String::from( - "Moves must specify a position on the game board.", - )); - } - let y: u8 = (y.to_digit(10).unwrap() - 1) as u8; - - let c = chars.next(); - if c.is_none() { - return Err(String::from("Moves must specify a move direction.")); - } - - let c = c.unwrap(); - // This is so cool! Rust supports some very nice patterns, and - // checks for uninitialised variables too! - let dir; - match c { - '+' => dir = Direction::Up, - '-' => dir = Direction::Down, - '<' => dir = Direction::Left, - '>' => dir = Direction::Right, - _ => return Err(String::from("The valid directions are +,-,<, and >.")), - } - - let mut drops: Vec = Vec::new(); - for d in chars { - if let Some(u) = d.to_digit(10) { - if u > 9 { - return Err(String::from( - "No more than 8 pieces may be dropped on a given square.", - )); - } else { - drops.push(u as u8) - } - } else { - return Err(String::from( - "A move must specify a number of pieces dropped for each square.", - )); - } - } - - let pos = Position { x: x, y: y }; - - let sum = drops.iter().map(|&d| d as u32).sum::(); - if sum == 0 { - // Omitted all the drops, it's a total stack move - drops.push(picked_up); - } else if sum != picked_up as u32 { - return Err(format!( - "The move called for {} stones, but {} were dropped.", - picked_up, sum - )); - } - - Ok(Action::Move(pos, dir, picked_up, drops)) + let mut chars = mv.chars(); + + let c = chars.next(); + if c.is_none() { + return Err(String::from("Empty string cannot be parsed.")); + } + + let x; + let picked_up; + let dc = c.unwrap(); + if (dc >= 'a') && (dc <= 'h') { + // Optional drop number omitted, assume everything + x = dc; + picked_up = 1; + } else { + if (dc < '1') || ('9' < dc) { + return Err(String::from( + "Moves must begin with a digit in 1-8 indicating the stones picked up.", + )); + } + picked_up = dc.to_digit(10).unwrap() as u8; + + let c = chars.next(); + if c.is_none() { + return Err(String::from("Moves must specify a stack position.")); + } + + x = c.unwrap(); + } + + if (x < 'a') || (x > 'h') { + return Err(String::from( + "Moves must specify a valid position on the game board.", + )); + } + let x: u8 = x as u8 - 'a' as u8; + + let c = chars.next(); + if c.is_none() { + return Err(String::from("Moves must specify a stack position.")); + } + + let y = c.unwrap(); + if (y < '1') || (y > '8') { + return Err(String::from( + "Moves must specify a position on the game board.", + )); + } + let y: u8 = (y.to_digit(10).unwrap() - 1) as u8; + + let c = chars.next(); + if c.is_none() { + return Err(String::from("Moves must specify a move direction.")); + } + + let c = c.unwrap(); + // This is so cool! Rust supports some very nice patterns, and + // checks for uninitialised variables too! + let dir; + match c { + '+' => dir = Direction::Up, + '-' => dir = Direction::Down, + '<' => dir = Direction::Left, + '>' => dir = Direction::Right, + _ => return Err(String::from("The valid directions are +,-,<, and >.")), + } + + let mut drops: Vec = Vec::new(); + for d in chars { + if let Some(u) = d.to_digit(10) { + if u > 9 { + return Err(String::from( + "No more than 8 pieces may be dropped on a given square.", + )); + } else { + drops.push(u as u8) + } + } else { + return Err(String::from( + "A move must specify a number of pieces dropped for each square.", + )); + } + } + + let pos = Position { x: x, y: y }; + + let sum = drops.iter().map(|&d| d as u32).sum::(); + if sum == 0 { + // Omitted all the drops, it's a total stack move + drops.push(picked_up); + } else if sum != picked_up as u32 { + return Err(format!( + "The move called for {} stones, but {} were dropped.", + picked_up, sum + )); + } + + Ok(Action::Move(pos, dir, picked_up, drops)) } fn parse_place(pl: &str, stone_owner: Player) -> Result { - let mut chars = pl.chars(); - - let c = chars.next(); - if c.is_none() { - return Err(String::from("An action cannot be blank.")); - } - - let stone_c = c.unwrap(); - - let stone; - let x; - if (stone_c == 'F') || (stone_c == 'C') || (stone_c == 'S') { - match stone_c { - 'C' => stone = Stone::Capstone, - 'S' => stone = Stone::Standing, - _ => stone = Stone::Flat, - } - let c = chars.next(); - if c.is_none() { - return Err(String::from( - "Placements must specify a position on the game board.", - )); - } - x = c.unwrap(); - } else { - stone = Stone::Flat; - x = stone_c; - } - - if (x < 'a') || (x > 'h') { - return Err(if (x >= 'A') && (x <= 'Z') { - format!("Unrecognised stone type '{}' in placement.", x) - } else { - String::from("Placements must specify a valid position on the game board.") - }); - } - let x: u8 = x as u8 - 'a' as u8; - - let c = chars.next(); - if c.is_none() { - return Err(String::from( - "Placements must specify a position on the game board.", - )); - } - - let y = c.unwrap(); - if (y < '1') || (y > '8') { - return Err(String::from( - "Placements must specify a valid position on the game board.", - )); - } - let y: u8 = (y.to_digit(10).unwrap() - 1) as u8; - - Ok(Action::Place(stone_owner, Position { x: x, y: y }, stone)) + let mut chars = pl.chars(); + + let c = chars.next(); + if c.is_none() { + return Err(String::from("An action cannot be blank.")); + } + + let stone_c = c.unwrap(); + + let stone; + let x; + if (stone_c == 'F') || (stone_c == 'C') || (stone_c == 'S') { + match stone_c { + 'C' => stone = Stone::Capstone, + 'S' => stone = Stone::Standing, + _ => stone = Stone::Flat, + } + let c = chars.next(); + if c.is_none() { + return Err(String::from( + "Placements must specify a position on the game board.", + )); + } + x = c.unwrap(); + } else { + stone = Stone::Flat; + x = stone_c; + } + + if (x < 'a') || (x > 'h') { + return Err(if (x >= 'A') && (x <= 'Z') { + format!("Unrecognised stone type '{}' in placement.", x) + } else { + String::from("Placements must specify a valid position on the game board.") + }); + } + let x: u8 = x as u8 - 'a' as u8; + + let c = chars.next(); + if c.is_none() { + return Err(String::from( + "Placements must specify a position on the game board.", + )); + } + + let y = c.unwrap(); + if (y < '1') || (y > '8') { + return Err(String::from( + "Placements must specify a valid position on the game board.", + )); + } + let y: u8 = (y.to_digit(10).unwrap() - 1) as u8; + + Ok(Action::Place(stone_owner, Position { x: x, y: y }, stone)) } pub fn parse_action(stone_owner: Player, act: &str) -> Result { - if act - .chars() - .any(|c| c == '+' || c == '-' || c == '>' || c == '<') - { - parse_move(act) - } else { - parse_place(act, stone_owner) - } + if act + .chars() + .any(|c| c == '+' || c == '-' || c == '>' || c == '<') + { + parse_move(act) + } else { + parse_place(act, stone_owner) + } } pub fn parse_start_type(st: &str) -> Result { - let st = st.trim().to_uppercase(); + let st = st.trim().to_uppercase(); - if st == StartType::FCS.to_string() { - return Ok(StartType::FCS); - }; + if st == StartType::FCS.to_string() { + return Ok(StartType::FCS); + }; - if st == StartType::FES.to_string() { - return Ok(StartType::FES); - }; + if st == StartType::FES.to_string() { + return Ok(StartType::FES); + }; - if st == StartType::TPS.to_string() { - return Ok(StartType::TPS); - }; + if st == StartType::TPS.to_string() { + return Ok(StartType::TPS); + }; - if st == StartType::CZS.to_string() { - return Ok(StartType::CZS); - }; + if st == StartType::CZS.to_string() { + return Ok(StartType::CZS); + }; - if st.len() < 4 { - return Err(String::from( - "Expecting CPSn as + if st.len() < 4 { + return Err(String::from( + "Expecting CPSn as alternatives failed to match, but variant string was too short.", - )); - } else { - if st[..3] == String::from("CPS") { - let num = st[3..].parse::(); - match num { - Err(e) => { - return Err(format!( - "Failed to parse number, {}. CPS must be + )); + } else { + if st[..3] == String::from("CPS") { + let num = st[3..].parse::(); + match num { + Err(e) => { + return Err(format!( + "Failed to parse number, {}. CPS must be immediately followed by a positive integer < 256, e.g., CPS1.", - e.to_string() - )) - } - Ok(n) => return Ok(StartType::CPS(n)), - } - } - } - - return Err(format!("Unknown start type ``{}''", st)); + e.to_string() + )) + } + Ok(n) => return Ok(StartType::CPS(n)), + } + } + } + + return Err(format!("Unknown start type ``{}''", st)); } -- cgit v1.3.1