From ed67a5b00a991f23770b5a3e4ae3cce7dd051762 Mon Sep 17 00:00:00 2001 From: Piotr Myszka Date: Fri, 24 Nov 2023 12:51:48 +0100 Subject: [PATCH 1/2] fix: recognizing start/end of game when reading from a PGN --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/pgn.rs | 59 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 57dc10b6..0b7e819c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1093,6 +1093,7 @@ dependencies = [ "quick-xml 0.30.0", "rand 0.8.5", "rayon", + "regex", "reqwest", "rusqlite", "serde", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 60cda968..a47e0625 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -53,6 +53,7 @@ oauth2 = "4.4.2" axum = "0.6.20" tar = "0.4.40" sysinfo = "0.29.10" +regex = "1.8.4" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/pgn.rs b/src-tauri/src/pgn.rs index c6fc3005..9b4c8923 100644 --- a/src-tauri/src/pgn.rs +++ b/src-tauri/src/pgn.rs @@ -3,6 +3,8 @@ use std::{ io::{self, BufRead, BufReader, Read, Seek, SeekFrom, Write}, path::PathBuf, }; +use lazy_static::lazy_static; +use regex::Regex; use crate::{error::Error, AppState}; @@ -15,6 +17,10 @@ struct PgnParser { start: u64, } +lazy_static! { + static ref GAME_TERMINATION_MARKER : Regex = Regex::new(r"(1-0|0-1|1/2-1/2|\*)$").unwrap(); +} + impl PgnParser { fn new(file: File) -> Self { let mut reader = BufReader::new(file); @@ -67,7 +73,7 @@ impl PgnParser { if bytes == 0 { break; } - if line.starts_with('[') { + if line.starts_with("[Event") { if new_game { count += 1; if count == n { @@ -85,21 +91,22 @@ impl PgnParser { } fn read_game(&mut self) -> io::Result { - let mut new_game = false; + let mut new_game = true; self.game.clear(); while let Ok(bytes) = self.reader.read_line(&mut self.line) { if bytes == 0 { break; } - if self.line.starts_with('[') { - if new_game { - break; - } - } else { - new_game = true; - } self.game.push_str(&self.line); + + if is_end_of_game(&self.line) { + new_game = false; + } + self.line.clear(); + if (!new_game) { + break; + } } Ok(self.game.clone()) } @@ -235,3 +242,37 @@ pub async fn write_game( Ok(()) } + +pub fn is_end_of_game(line: &str) -> bool { + GAME_TERMINATION_MARKER.is_match(line.trim()) +} + +#[test] +fn test_gtm_white_won() { + let s = String::from("1. e4 f5 2. d4 g5 1-0"); + assert!(is_end_of_game(&*s)) +} + +#[test] +fn test_gtm_black_won() { + let s = String::from("1. e4 f5 2. d4 g5 0-1"); + assert!(is_end_of_game(&*s)) +} + +#[test] +fn test_gtm_draw() { + let s = String::from("1. e4 f5 2. d4 g5 1/2-1/2 "); + assert!(is_end_of_game(&*s)) +} + +#[test] +fn test_gtm_unknown() { + let s = String::from("1. e4 f5 2. d4 g5 *\n"); + assert!(is_end_of_game(&*s)) +} + +#[test] +fn test_no_gtm() { + let s = String::from("1. e4 f5 2. d4 g5\n"); + assert!(!is_end_of_game(&*s)) +} From 716ee2569b786231f88a9172398dd61c72b5bf86 Mon Sep 17 00:00:00 2001 From: Piotr Myszka Date: Fri, 24 Nov 2023 13:27:23 +0100 Subject: [PATCH 2/2] don't allow bogus markers, like 11-0 --- src-tauri/src/pgn.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/pgn.rs b/src-tauri/src/pgn.rs index 9b4c8923..7a2335b6 100644 --- a/src-tauri/src/pgn.rs +++ b/src-tauri/src/pgn.rs @@ -18,7 +18,7 @@ struct PgnParser { } lazy_static! { - static ref GAME_TERMINATION_MARKER : Regex = Regex::new(r"(1-0|0-1|1/2-1/2|\*)$").unwrap(); + static ref GAME_TERMINATION_MARKER : Regex = Regex::new(r"\s+(1-0|0-1|1/2-1/2|\*)$").unwrap(); } impl PgnParser { @@ -271,6 +271,12 @@ fn test_gtm_unknown() { assert!(is_end_of_game(&*s)) } +#[test] +fn test_weird_gtm() { + let s = String::from("1. e4 f5 2. d4 g5 11-0\n"); + assert!(!is_end_of_game(&*s)) +} + #[test] fn test_no_gtm() { let s = String::from("1. e4 f5 2. d4 g5\n");