use std::fs::File;
use std::io::{BufReader, Write};
use super::board::filter::BoardFilter;
use super::moves;
use super::Game;
pub struct Games {
games: Vec<Game>,
matcher: moves::Matches
}
impl Games {
pub fn new () -> Games {
let games: Vec<Game> = vec![];
Games {
games,
matcher: moves::Matches::new()
}
}
pub fn from_file (filename: &str) -> std::io::Result<Games> {
let mut games = Games::new();
games.add_games(filename)?;
Ok(games)
}
pub fn add_games (&mut self, filename: &str) -> std::io::Result<()> {
let file = File::open(filename).expect("Error in opening file");
let mut reader = BufReader::new(file);
loop {
let game = Game::from_pgn(&mut reader, &self.matcher)?;
match game {
Some(game) => self.games.push(game),
None => break,
};
}
Ok(())
}
pub fn iter(&self) -> std::slice::Iter<'_, Game> {
self.games.iter()
}
pub fn search(&self, filter: &BoardFilter) -> Games {
let mut selected_games = vec![];
for game in &self.games {
if game.meets_filter(&filter) {
selected_games.push(game.clone());
}
}
Games {
games: selected_games,
matcher: moves::Matches::new()
}
}
pub fn to_file(&self, filename: &str) -> std::io::Result<()> {
let mut out_file = File::create(&filename)?;
for game in &self.games {
game.to_file(&mut out_file)?;
out_file.write_all(b"\n")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_read_file () {
match Games::from_file("src/samples/games1.pgn") {
Ok(db) => {
assert_eq!(2, db.games.len());
let game = &db.games[0];
assert_eq!(Some(&"F/S Return Match".to_string()), game.header.get("Event"));
assert_eq!(Some(&"Belgrade, Serbia JUG".to_string()), game.header.get("Site"));
assert_eq!(Some(&"1992.11.04".to_string()), game.header.get("Date"));
assert_eq!(Some(&"29".to_string()), game.header.get("Round"));
assert_eq!(Some(&"Fischer, Robert J.".to_string()), game.header.get("White"));
assert_eq!(Some(&"Spassky, Boris V.".to_string()), game.header.get("Black"));
assert_eq!(85, game.total_half_moves());
let game = &db.games[1];
assert_eq!(Some(&"8th RUS-CHN Summit Men Classical".to_string()), game.header.get("Event"));
assert_eq!(Some(&"2012.07.02".to_string()), game.header.get("Date"));
assert_eq!(103, game.total_half_moves());
},
Err(_) => {
assert!(false);
},
};
}
#[test]
fn test_read_file_with_accent () {
match Games::from_file("src/samples/games3.pgn") {
Ok(db) => {
assert_eq!(2, db.games.len());
},
Err(_) => {
assert!(false);
},
};
}
}