From cc4f8c151559956b403303a57a01f4b8f880b6d2 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Sun, 19 Jan 2025 12:31:26 -0500 Subject: [PATCH] Fix warnings mostly in the SGF parser --- Taskfile.yml | 6 ++ otg/gtk/src/views/game_review.rs | 3 - sgf/src/parser.rs | 171 ++++++++++++++++++------------- sgf/src/types.rs | 1 + tree/src/lib.rs | 4 +- 5 files changed, 110 insertions(+), 75 deletions(-) create mode 100644 Taskfile.yml diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..919d914 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,6 @@ +version: '3' + +tasks: + lint: + cmds: + - cargo watch -x clippy diff --git a/otg/gtk/src/views/game_review.rs b/otg/gtk/src/views/game_review.rs index e88c50c..181059a 100644 --- a/otg/gtk/src/views/game_review.rs +++ b/otg/gtk/src/views/game_review.rs @@ -163,9 +163,6 @@ impl GameReview { *self.review_tree.borrow_mut() = Some(review_tree); } - fn redraw(&self) { - } - pub fn widget(&self) -> gtk::Widget { self.widget.clone().upcast::() } diff --git a/sgf/src/parser.rs b/sgf/src/parser.rs index 8492dd2..4ee8735 100644 --- a/sgf/src/parser.rs +++ b/sgf/src/parser.rs @@ -10,7 +10,7 @@ use nom::{ IResult, Parser, }; use serde::{Deserialize, Serialize}; -use std::{fmt::Write, num::ParseIntError, time::Duration}; +use std::{fmt::Display, num::ParseIntError, time::Duration}; impl From for Error { fn from(_: ParseSizeError) -> Self { @@ -142,9 +142,9 @@ impl From<&GameType> for String { } } -impl ToString for GameType { - fn to_string(&self) -> String { - String::from(self) +impl Display for GameType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", String::from(self)) } } @@ -189,12 +189,15 @@ pub struct Tree { pub root: Node, } -impl ToString for Tree { - fn to_string(&self) -> String { - format!("({})", self.root.to_string()) +impl Display for Tree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({})", self.root) } } +struct Properties<'a>(&'a Vec); +struct Nodes<'a>(&'a Vec); + #[derive(Clone, Debug, PartialEq)] pub struct Node { pub properties: Vec, @@ -264,8 +267,12 @@ impl Node { } } -impl ToString for Node { - fn to_string(&self) -> String { +impl Display for Node { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, ";{}", Properties(&self.properties))?; + write!(f, "{}", Nodes(&self.next))?; + Ok(()) + /* let props = self .properties .iter() @@ -281,11 +288,36 @@ impl ToString for Node { } else { self.next .iter() - .map(|node| format!("({})", node.to_string())) + .map(|node| write!(f, "({})", node.to_string())) .collect::>() .join("") }; - format!(";{}{}", props, next) + write!(f, ";{}{}", props, next) + */ + } +} + +impl Display for Properties<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for property in self.0.iter() { + write!(f, "{}", property)?; + } + Ok(()) + } +} + +impl Display for Nodes<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.0.len() == 1 { + for node in self.0.iter() { + write!(f, "{}", node)?; + } + } else { + for node in self.0.iter() { + write!(f, "({})", node)?; + } + } + Ok(()) } } @@ -460,95 +492,96 @@ pub struct UnknownProperty { pub value: String, } -impl ToString for Property { - fn to_string(&self) -> String { +impl Display for Property { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Property::Move((color, Move::Move(mv))) => { - format!("{}[{}]", color.abbreviation(), mv) + write!(f, "{}[{}]", color.abbreviation(), mv) } Property::Move((color, Move::Pass)) => { - format!("{}[]", color.abbreviation()) + write!(f, "{}[]", color.abbreviation()) } Property::TimeLeft((color, time)) => { - format!("{}[{}]", color.abbreviation(), time.as_secs()) + write!(f, "{}[{}]", color.abbreviation(), time.as_secs()) } - Property::Comment(value) => format!("C[{}]", value), - Property::Annotation(Annotation::BadMove) => "BM[]".to_owned(), - Property::Annotation(Annotation::DoubtfulMove) => "DO[]".to_owned(), - Property::Annotation(Annotation::InterestingMove) => "IT[]".to_owned(), - Property::Annotation(Annotation::Tesuji) => "TE[]".to_owned(), - Property::Application(app) => format!("AP[{}]", app), - Property::Charset(set) => format!("CA[{}]", set), - Property::FileFormat(ff) => format!("FF[{}]", ff), - Property::GameType(gt) => format!("GM[{}]", gt.to_string()), + Property::Comment(value) => write!(f, "C[{}]", value), + Property::Annotation(Annotation::BadMove) => write!(f, "BM[]"), + Property::Annotation(Annotation::DoubtfulMove) => write!(f, "DO[]"), + Property::Annotation(Annotation::InterestingMove) => write!(f, "IT[]"), + Property::Annotation(Annotation::Tesuji) => write!(f, "TE[]"), + Property::Application(app) => write!(f, "AP[{}]", app), + Property::Charset(set) => write!(f, "CA[{}]", set), + Property::FileFormat(ff) => write!(f, "FF[{}]", ff), + Property::GameType(gt) => write!(f, "GM[{}]", gt), Property::VariationDisplay => unimplemented!(), Property::BoardSize(Size { width, height }) => { if width == height { - format!("SZ[{}]", width) + write!(f, "SZ[{}]", width) } else { - format!("SZ[{}:{}]", width, height) + write!(f, "SZ[{}:{}]", width, height) } } Property::SetupBlackStones(positions) => { - format!("AB[{}]", positions.compressed_list(),) + write!(f, "AB[{}]", positions.compressed_list(),) } Property::ClearStones(positions) => { - format!("AE[{}]", positions.compressed_list(),) + write!(f, "AE[{}]", positions.compressed_list(),) } Property::SetupWhiteStones(positions) => { - format!("AW[{}]", positions.compressed_list(),) + write!(f, "AW[{}]", positions.compressed_list(),) } - Property::NextPlayer(color) => format!("PL[{}]", color.abbreviation()), - Property::Evaluation(Evaluation::Even) => "DM[]".to_owned(), - Property::Evaluation(Evaluation::GoodForBlack) => "GB[]".to_owned(), - Property::Evaluation(Evaluation::GoodForWhite) => "GW[]".to_owned(), - Property::Evaluation(Evaluation::Unclear) => "UC[]".to_owned(), - Property::Hotspot => "HO[]".to_owned(), - Property::Value(value) => format!("V[{}]", value), - Property::Annotator(value) => format!("AN[{}]", value), - Property::BlackRank(value) => format!("BR[{}]", value), - Property::BlackTeam(value) => format!("BT[{}]", value), - Property::Copyright(value) => format!("CP[{}]", value), + Property::NextPlayer(color) => write!(f, "PL[{}]", color.abbreviation()), + Property::Evaluation(Evaluation::Even) => write!(f, "DM[]"), + Property::Evaluation(Evaluation::GoodForBlack) => write!(f, "GB[]"), + Property::Evaluation(Evaluation::GoodForWhite) => write!(f, "GW[]"), + Property::Evaluation(Evaluation::Unclear) => write!(f, "UC[]"), + Property::Hotspot => write!(f, "HO[]"), + Property::Value(value) => write!(f, "V[{}]", value), + Property::Annotator(value) => write!(f, "AN[{}]", value), + Property::BlackRank(value) => write!(f, "BR[{}]", value), + Property::BlackTeam(value) => write!(f, "BT[{}]", value), + Property::Copyright(value) => write!(f, "CP[{}]", value), Property::EventDates(_) => unimplemented!(), - Property::EventName(value) => format!("EV[{}]", value), - Property::GameName(value) => format!("GN[{}]", value), - Property::ExtraGameInformation(value) => format!("GC[{}]", value), - Property::GameOpening(value) => format!("ON[{}]", value), - Property::Overtime(value) => format!("OT[{}]", value), - Property::BlackPlayer(value) => format!("PB[{}]", value), - Property::GameLocation(value) => format!("PC[{}]", value), - Property::WhitePlayer(value) => format!("PW[{}]", value), + Property::EventName(value) => write!(f, "EV[{}]", value), + Property::GameName(value) => write!(f, "GN[{}]", value), + Property::ExtraGameInformation(value) => write!(f, "GC[{}]", value), + Property::GameOpening(value) => write!(f, "ON[{}]", value), + Property::Overtime(value) => write!(f, "OT[{}]", value), + Property::BlackPlayer(value) => write!(f, "PB[{}]", value), + Property::GameLocation(value) => write!(f, "PC[{}]", value), + Property::WhitePlayer(value) => write!(f, "PW[{}]", value), Property::Result(_) => unimplemented!(), - Property::Round(value) => format!("RO[{}]", value), - Property::Ruleset(value) => format!("RU[{}]", value), - Property::Source(value) => format!("SO[{}]", value), - Property::TimeLimit(value) => format!("TM[{}]", value.as_secs()), - Property::User(value) => format!("US[{}]", value), - Property::WhiteRank(value) => format!("WR[{}]", value), - Property::WhiteTeam(value) => format!("WT[{}]", value), + Property::Round(value) => write!(f, "RO[{}]", value), + Property::Ruleset(value) => write!(f, "RU[{}]", value), + Property::Source(value) => write!(f, "SO[{}]", value), + Property::TimeLimit(value) => write!(f, "TM[{}]", value.as_secs()), + Property::User(value) => write!(f, "US[{}]", value), + Property::WhiteRank(value) => write!(f, "WR[{}]", value), + Property::WhiteTeam(value) => write!(f, "WT[{}]", value), Property::Territory(Color::White, positions) => { - positions - .iter() - .fold("TW".to_owned(), |mut output, Position(p)| { - let _ = write!(output, "{}", p); - output - }) + write!(f, "TW[{}]", Positions(positions)) } Property::Territory(Color::Black, positions) => { - positions - .iter() - .fold("TB".to_owned(), |mut output, Position(p)| { - let _ = write!(output, "{}", p); - output - }) + write!(f, "TB[{}]", Positions(positions)) } Property::Unknown(UnknownProperty { ident, value }) => { - format!("{}[{}]", ident, value) + write!(f, "{}[{}]", ident, value) } } } } +struct Positions<'a>(&'a Vec); + +impl Display for Positions<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for Position(p) in self.0.iter() { + write!(f, "{}", p)?; + } + Ok(()) + } +} + pub fn parse_collection<'a, E: nom::error::ParseError<&'a str>>( input: &'a str, ) -> IResult<&'a str, Vec, E> { diff --git a/sgf/src/types.rs b/sgf/src/types.rs index 723164d..0d4777d 100644 --- a/sgf/src/types.rs +++ b/sgf/src/types.rs @@ -53,6 +53,7 @@ pub enum Error { // InvalidField, // InvalidBoardSize, Incomplete, + #[allow(dead_code)] InvalidSgf(VerboseNomError), } diff --git a/tree/src/lib.rs b/tree/src/lib.rs index 0a4f72f..21db1d2 100644 --- a/tree/src/lib.rs +++ b/tree/src/lib.rs @@ -62,14 +62,12 @@ impl Tree { // Do a depth-first-search in order to get the path to a node. Start with a naive recursive // implementation, then switch to a stack-based implementation in order to avoid exceeding the // stack. - /* - pub fn path_to(&self, f: F) -> Vec> + pub fn path_to(&self, _f: F) -> Vec> where F: FnOnce(&T) -> bool + Copy, { unimplemented!() } - */ /// Convert each node of a tree from type T to type U pub fn map(&self, op: F) -> Tree