mod date; pub use date::Date; mod go; pub use go::{GameTree, GameType, Rank}; mod tree; use tree::parse_collection; use thiserror::Error; #[derive(Debug)] pub enum Error<'a> { InvalidField, InvalidBoardSize, Incomplete, InvalidSgf(nom::error::VerboseError<&'a str>), } #[derive(Debug, PartialEq, Error)] pub enum ParseError { #[error("An unknown error was found")] NomError(nom::error::Error), } impl From> for ParseError { fn from(err: nom::error::Error<&str>) -> Self { Self::NomError(nom::error::Error { input: err.input.to_owned(), code: err.code.clone(), }) } } pub enum Game { Go(go::Game), Unsupported(tree::Tree), } pub fn parse_sgf<'a>(input: &'a str) -> Result, Error<'a>> { let (_, trees) = parse_collection::>(input)?; Ok(trees .into_iter() .map(|t| match t.sequence[0].find_prop("GM") { Some(prop) if prop.values == vec!["1".to_owned()] => Game::Go(go::Game {}), _ => 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(), }) */ } } */