Resolve warnings in the SGF library

This commit is contained in:
Savanni D'Gerinel 2023-10-05 11:41:00 -04:00
parent 021fea819a
commit 88510e489e
4 changed files with 19 additions and 36 deletions

View File

@ -1,6 +1,6 @@
use chrono::{Datelike, NaiveDate}; use chrono::{Datelike, NaiveDate};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::num::ParseIntError; use std::{fmt, num::ParseIntError};
use thiserror::Error; use thiserror::Error;
use typeshare::typeshare; use typeshare::typeshare;
@ -11,9 +11,6 @@ pub enum Error {
#[error("Invalid date")] #[error("Invalid date")]
InvalidDate, InvalidDate,
#[error("unsupported date format")]
Unsupported,
} }
#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
@ -24,12 +21,12 @@ pub enum Date {
Date(chrono::NaiveDate), Date(chrono::NaiveDate),
} }
impl Date { impl fmt::Display for Date {
pub fn to_string(&self) -> String { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Date::Year(y) => format!("{}", y), Date::Year(y) => write!(f, "{}", y),
Date::YearMonth(y, m) => format!("{}-{}", y, m), Date::YearMonth(y, m) => write!(f, "{}-{}", y, m),
Date::Date(date) => format!("{}-{}-{}", date.year(), date.month(), date.day()), Date::Date(date) => write!(f, "{}-{}-{}", date.year(), date.month(), date.day()),
} }
} }
} }
@ -71,13 +68,13 @@ impl TryFrom<&str> for Date {
*/ */
fn parse_numbers(s: &str) -> Result<Vec<i32>, Error> { fn parse_numbers(s: &str) -> Result<Vec<i32>, Error> {
s.split("-") s.split('-')
.map(|s| s.parse::<i32>().map_err(|err| Error::ParseNumberError(err))) .map(|s| s.parse::<i32>().map_err(Error::ParseNumberError))
.collect::<Result<Vec<i32>, Error>>() .collect::<Result<Vec<i32>, Error>>()
} }
pub fn parse_date_field(s: &str) -> Result<Vec<Date>, Error> { pub fn parse_date_field(s: &str) -> Result<Vec<Date>, Error> {
let date_elements = s.split(","); let date_elements = s.split(',');
let mut dates = Vec::new(); let mut dates = Vec::new();
let mut most_recent: Option<Date> = None; let mut most_recent: Option<Date> = None;
@ -96,9 +93,9 @@ pub fn parse_date_field(s: &str) -> Result<Vec<Date>, Error> {
None => Date::Year(*v1), None => Date::Year(*v1),
}, },
[v1, v2] => Date::YearMonth(*v1, *v2 as u32), [v1, v2] => Date::YearMonth(*v1, *v2 as u32),
[v1, v2, v3, ..] => Date::Date( [v1, v2, v3, ..] => {
NaiveDate::from_ymd_opt(v1.clone(), v2.clone() as u32, v3.clone() as u32).unwrap(), Date::Date(NaiveDate::from_ymd_opt(*v1, *v2 as u32, *v3 as u32).unwrap())
), }
}; };
dates.push(new_date.clone()); dates.push(new_date.clone());
most_recent = Some(new_date); most_recent = Some(new_date);

View File

@ -95,6 +95,7 @@ impl Deref for Game {
impl TryFrom<Tree> for Game { impl TryFrom<Tree> for Game {
type Error = Error; type Error = Error;
#[allow(clippy::field_reassign_with_default)]
fn try_from(tree: Tree) -> Result<Self, Self::Error> { fn try_from(tree: Tree) -> Result<Self, Self::Error> {
let board_size = match tree.root.find_prop("SZ") { let board_size = match tree.root.find_prop("SZ") {
Some(prop) => Size::try_from(prop.values[0].as_str())?, Some(prop) => Size::try_from(prop.values[0].as_str())?,
@ -131,7 +132,7 @@ impl TryFrom<Tree> for Game {
.root .root
.find_prop("TM") .find_prop("TM")
.and_then(|prop| prop.values[0].parse::<u64>().ok()) .and_then(|prop| prop.values[0].parse::<u64>().ok())
.and_then(|seconds| Some(std::time::Duration::from_secs(seconds))); .map(std::time::Duration::from_secs);
info.date = tree info.date = tree
.root .root
@ -182,7 +183,7 @@ pub enum Rank {
impl TryFrom<&str> for Rank { impl TryFrom<&str> for Rank {
type Error = String; type Error = String;
fn try_from(r: &str) -> Result<Rank, Self::Error> { fn try_from(r: &str) -> Result<Rank, Self::Error> {
let parts = r.split(" ").map(|s| s.to_owned()).collect::<Vec<String>>(); let parts = r.split(' ').map(|s| s.to_owned()).collect::<Vec<String>>();
let cnt = parts[0].parse::<u8>().map_err(|err| format!("{:?}", err))?; let cnt = parts[0].parse::<u8>().map_err(|err| format!("{:?}", err))?;
match parts[1].to_ascii_lowercase().as_str() { match parts[1].to_ascii_lowercase().as_str() {
"kyu" => Ok(Rank::Kyu(cnt)), "kyu" => Ok(Rank::Kyu(cnt)),
@ -250,7 +251,7 @@ impl TryFrom<&str> for GameResult {
} else if s == "Void" { } else if s == "Void" {
Ok(GameResult::Annulled) Ok(GameResult::Annulled)
} else { } else {
let parts = s.split("+").collect::<Vec<&str>>(); let parts = s.split('+').collect::<Vec<&str>>();
let res = match parts[0].to_ascii_lowercase().as_str() { let res = match parts[0].to_ascii_lowercase().as_str() {
"b" => GameResult::Black, "b" => GameResult::Black,
"w" => GameResult::White, "w" => GameResult::White,

View File

@ -51,7 +51,7 @@ impl From<nom::error::Error<&str>> for ParseError {
fn from(err: nom::error::Error<&str>) -> Self { fn from(err: nom::error::Error<&str>) -> Self {
Self::NomError(nom::error::Error { Self::NomError(nom::error::Error {
input: err.input.to_owned(), input: err.input.to_owned(),
code: err.code.clone(), code: err.code,
}) })
} }
} }

View File

@ -2,7 +2,7 @@ use crate::Error;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{escaped_transform, tag}, bytes::complete::{escaped_transform, tag},
character::complete::{alpha1, digit1, multispace0, multispace1, none_of}, character::complete::{alpha1, multispace0, multispace1, none_of},
combinator::{opt, value}, combinator::{opt, value},
multi::{many0, many1, separated_list1}, multi::{many0, many1, separated_list1},
IResult, IResult,
@ -101,7 +101,7 @@ impl Node {
.cloned() .cloned()
} }
pub fn next<'a>(&'a self) -> Option<&'a Node> { pub fn next(&self) -> Option<&Node> {
self.next.get(0) self.next.get(0)
} }
} }
@ -209,21 +209,6 @@ fn parse_propval_text<'a, E: nom::error::ParseError<&'a str>>(
Ok((input, value.map(|v| v.to_owned()))) Ok((input, value.map(|v| v.to_owned())))
} }
pub fn parse_size<'a, E: nom::error::ParseError<&'a str>>(
input: &'a str,
) -> IResult<&'a str, Size, E> {
let (input, dimensions) = separated_list1(tag(":"), digit1)(input)?;
let (width, height) = match dimensions.as_slice() {
[width] => (width.parse::<i32>().unwrap(), width.parse::<i32>().unwrap()),
[width, height] => (
width.parse::<i32>().unwrap(),
height.parse::<i32>().unwrap(),
),
_ => (19, 19),
};
Ok((input, Size { width, height }))
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;