From 942e91009e94ac6ed72f3635d5129ff346ae65d1 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 19 Oct 2023 02:43:08 -0400 Subject: [PATCH] Disable sgf::go and provide a shim for a game --- kifu/core/src/database.rs | 14 +++-- kifu/core/src/ui/elements/game_preview.rs | 10 ++-- kifu/core/src/ui/home.rs | 2 +- sgf/src/date.rs | 3 ++ sgf/src/go.rs | 44 ---------------- sgf/src/lib.rs | 46 +++-------------- sgf/src/types.rs | 63 +++++++++++++++++++++++ 7 files changed, 84 insertions(+), 98 deletions(-) create mode 100644 sgf/src/types.rs diff --git a/kifu/core/src/database.rs b/kifu/core/src/database.rs index b98b885..1fbb9ca 100644 --- a/kifu/core/src/database.rs +++ b/kifu/core/src/database.rs @@ -1,6 +1,6 @@ use std::{io::Read, path::PathBuf}; -use sgf::{go, parse_sgf, Game}; +use sgf::{parse_sgf, Game}; use thiserror::Error; #[derive(Error, Debug)] @@ -21,12 +21,12 @@ impl From for Error { #[derive(Debug)] pub struct Database { - games: Vec, + games: Vec, } impl Database { pub fn open_path(path: PathBuf) -> Result { - let mut games: Vec = Vec::new(); + let mut games: Vec = Vec::new(); let extension = PathBuf::from("sgf").into_os_string(); @@ -43,10 +43,7 @@ impl Database { match parse_sgf(&buffer) { Ok(sgfs) => { for sgf in sgfs { - match sgf { - Game::Go(game) => games.push(game), - Game::Unsupported(_) => {} - } + games.push(sgf); } } Err(err) => println!("Error parsing {:?}: {:?}", entry.path(), err), @@ -60,7 +57,7 @@ impl Database { Ok(Database { games }) } - pub fn all_games(&self) -> impl Iterator { + pub fn all_games(&self) -> impl Iterator { self.games.iter() } } @@ -78,6 +75,7 @@ mod test { assert_eq!(db.all_games().count(), 0); } + #[ignore] #[test] fn it_reads_five_games_from_database() { let db = diff --git a/kifu/core/src/ui/elements/game_preview.rs b/kifu/core/src/ui/elements/game_preview.rs index fbd00ea..3a59958 100644 --- a/kifu/core/src/ui/elements/game_preview.rs +++ b/kifu/core/src/ui/elements/game_preview.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use sgf::go::{Game, GameResult, Win}; +use sgf::{Game, GameResult, Win}; use typeshare::typeshare; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -23,13 +23,13 @@ impl GamePreviewElement { None => "unknown".to_owned(), }; - let black_player = match game.info.black_rank { - Some(rank) => format!("{} ({})", black_player, rank.to_string()), + let black_player = match &game.info.black_rank { + Some(rank) => format!("{} ({})", black_player, rank), None => black_player, }; - let white_player = match game.info.white_rank { - Some(rank) => format!("{} ({})", white_player, rank.to_string()), + let white_player = match &game.info.white_rank { + Some(rank) => format!("{} ({})", white_player, rank), None => white_player, }; diff --git a/kifu/core/src/ui/home.rs b/kifu/core/src/ui/home.rs index 59a064b..f19f8d4 100644 --- a/kifu/core/src/ui/home.rs +++ b/kifu/core/src/ui/home.rs @@ -1,6 +1,6 @@ use crate::ui::{Action, GamePreviewElement}; use serde::{Deserialize, Serialize}; -use sgf::go::Game; +use sgf::Game; use typeshare::typeshare; fn rank_strings() -> Vec { diff --git a/sgf/src/date.rs b/sgf/src/date.rs index 8de0e1b..f11c63e 100644 --- a/sgf/src/date.rs +++ b/sgf/src/date.rs @@ -4,6 +4,7 @@ use std::{fmt, num::ParseIntError}; use thiserror::Error; use typeshare::typeshare; +#[allow(dead_code)] #[derive(Debug, Error, PartialEq)] pub enum Error { #[error("Failed to parse integer {0}")] @@ -67,12 +68,14 @@ impl TryFrom<&str> for Date { } */ +#[allow(dead_code)] fn parse_numbers(s: &str) -> Result, Error> { s.split('-') .map(|s| s.parse::().map_err(Error::ParseNumberError)) .collect::, Error>>() } +#[allow(dead_code)] pub fn parse_date_field(s: &str) -> Result, Error> { let date_elements = s.split(','); let mut dates = Vec::new(); diff --git a/sgf/src/go.rs b/sgf/src/go.rs index 2c226f4..2a605e0 100644 --- a/sgf/src/go.rs +++ b/sgf/src/go.rs @@ -234,50 +234,6 @@ pub struct GameInfo { pub result: Option, } -#[derive(Clone, Debug, PartialEq)] -pub enum GameResult { - Annulled, - Draw, - Black(Win), - White(Win), - Unknown(String), -} - -impl TryFrom<&str> for GameResult { - type Error = String; - fn try_from(s: &str) -> Result { - if s == "0" { - Ok(GameResult::Draw) - } else if s == "Void" { - Ok(GameResult::Annulled) - } else { - let parts = s.split('+').collect::>(); - let res = match parts[0].to_ascii_lowercase().as_str() { - "b" => GameResult::Black, - "w" => GameResult::White, - _ => return Ok(GameResult::Unknown(parts[0].to_owned())), - }; - match parts[1].to_ascii_lowercase().as_str() { - "r" | "resign" => Ok(res(Win::Resignation)), - "t" | "time" => Ok(res(Win::Time)), - "f" | "forfeit" => Ok(res(Win::Forfeit)), - _ => { - let score = parts[1].parse::().unwrap(); - Ok(res(Win::Score(score))) - } - } - } - } -} - -#[derive(Clone, Debug, PartialEq)] -pub enum Win { - Score(f32), - Resignation, - Forfeit, - Time, -} - /* enum PropType { Move, diff --git a/sgf/src/lib.rs b/sgf/src/lib.rs index 3c42229..cd3d056 100644 --- a/sgf/src/lib.rs +++ b/sgf/src/lib.rs @@ -1,13 +1,14 @@ mod date; pub use date::Date; -pub mod go; - mod tree; -use tree::parse_collection; +pub use tree::parse_collection; use thiserror::Error; +mod types; +pub use types::*; + #[derive(Debug)] pub enum Error { InvalidField, @@ -56,41 +57,6 @@ impl From> for ParseError { } } -pub enum Game { - Go(go::Game), - Unsupported(tree::Tree), +pub fn parse_sgf(_input: &str) -> Result, Error> { + Ok(vec![Game::default()]) } - -pub fn parse_sgf(input: &str) -> Result, Error> { - let (_, trees) = parse_collection::>(input)?; - Ok(trees - .into_iter() - .map(|t| match t.root.find_prop("GM") { - Some(prop) if prop.values == vec!["1".to_owned()] => { - Game::Go(go::Game::try_from(t).expect("properly structured game tree")) - } - _ => Game::Unsupported(t), - }) - .collect::>()) -} - -/* -impl From<(&str, VerboseErrorKind)> for - -impl From> for ParseError { - fn from(err: nom::error::VerboseError<&str>) -> Self { - Self::NomErrors( - err.errors - .into_iter() - .map(|err| ParseError::from(err)) - .collect(), - ) - /* - Self::NomError(nom::error::Error { - input: err.input.to_owned(), - code: err.code.clone(), - }) - */ - } -} -*/ diff --git a/sgf/src/types.rs b/sgf/src/types.rs new file mode 100644 index 0000000..206719e --- /dev/null +++ b/sgf/src/types.rs @@ -0,0 +1,63 @@ +use crate::date::Date; + +/// This is a placeholder structure. It is not meant to represent a game, only to provide a mock +/// interface for code already written that expects a Game data type to exist. +#[derive(Debug, Default)] +pub struct Game { + pub info: GameInfo, +} + +#[derive(Debug, Default)] +pub struct GameInfo { + pub black_player: Option, + pub black_rank: Option, + pub white_player: Option, + pub white_rank: Option, + pub result: Option, + pub game_name: Option, + pub date: Vec, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum GameResult { + Annulled, + Draw, + Black(Win), + White(Win), + Unknown(String), +} + +impl TryFrom<&str> for GameResult { + type Error = String; + fn try_from(s: &str) -> Result { + if s == "0" { + Ok(GameResult::Draw) + } else if s == "Void" { + Ok(GameResult::Annulled) + } else { + let parts = s.split('+').collect::>(); + let res = match parts[0].to_ascii_lowercase().as_str() { + "b" => GameResult::Black, + "w" => GameResult::White, + _ => return Ok(GameResult::Unknown(parts[0].to_owned())), + }; + match parts[1].to_ascii_lowercase().as_str() { + "r" | "resign" => Ok(res(Win::Resignation)), + "t" | "time" => Ok(res(Win::Time)), + "f" | "forfeit" => Ok(res(Win::Forfeit)), + _ => { + let score = parts[1].parse::().unwrap(); + Ok(res(Win::Score(score))) + } + } + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub enum Win { + Score(f32), + Resignation, + Forfeit, + Time, +}