aboutsummaryrefslogtreecommitdiff
path: root/src/parser.rs
diff options
context:
space:
mode:
authortslil clingman <>2021-01-09 22:42:12 -0500
committertslil clingman <>2021-01-09 22:44:29 -0500
commita0f3a7f8ba9036d1fcb18941a54077082f15cf3c (patch)
treebb3943b7bc3cee704fbc7ad7c4e4c1ca0204d5f7 /src/parser.rs
parent1cb3c0ea50ce55278413dfd368285cb622130a30 (diff)
Added .rustfmt.toml, tabs for indentation, spaces for alignment
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs366
1 files changed, 183 insertions, 183 deletions
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 <https://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU General Public License
+ along with Takwrap. If not, see <https://www.gnu.org/licenses/>.
*/
use crate::game::*;
fn parse_move(mv: &str) -> Result<Action, String> {
- let mut chars = mv.chars();
+ let mut chars = mv.chars();
- let c = chars.next();
- if c.is_none() {
- return Err(String::from("Empty string cannot be parsed."));
- }
+ 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 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."));
- }
+ let c = chars.next();
+ if c.is_none() {
+ return Err(String::from("Moves must specify a stack position."));
+ }
- x = c.unwrap();
- }
+ 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;
+ 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 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 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 = 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 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<u8> = 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 mut drops: Vec<u8> = 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 pos = Position { x: x, y: y };
- let sum = drops.iter().map(|&d| d as u32).sum::<u32>();
- 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
- ));
- }
+ let sum = drops.iter().map(|&d| d as u32).sum::<u32>();
+ 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))
+ Ok(Action::Move(pos, dir, picked_up, drops))
}
fn parse_place(pl: &str, stone_owner: Player) -> Result<Action, String> {
- let mut chars = pl.chars();
+ let mut chars = pl.chars();
- let c = chars.next();
- if c.is_none() {
- return Err(String::from("An action cannot be blank."));
- }
+ let c = chars.next();
+ if c.is_none() {
+ return Err(String::from("An action cannot be blank."));
+ }
- let stone_c = c.unwrap();
+ 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;
- }
+ 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;
+ 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 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;
+ 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))
+ Ok(Action::Place(stone_owner, Position { x: x, y: y }, stone))
}
pub fn parse_action(stone_owner: Player, act: &str) -> Result<Action, String> {
- 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<StartType, String> {
- 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::<u8>();
- 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::<u8>();
+ 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)),
- }
- }
- }
+ e.to_string()
+ ))
+ }
+ Ok(n) => return Ok(StartType::CPS(n)),
+ }
+ }
+ }
- return Err(format!("Unknown start type ``{}''", st));
+ return Err(format!("Unknown start type ``{}''", st));
}