From e726ad19d393f92f0bd10870df42f2e089454b7a Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:14:55 -0400 Subject: [PATCH 1/9] Fixed doc tests --- src/action_tree.rs | 4 +- src/bet_size.rs | 126 +++++++++++++++++++++++++++++++-------------- 2 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/action_tree.rs b/src/action_tree.rs index a772701..27b520a 100644 --- a/src/action_tree.rs +++ b/src/action_tree.rs @@ -631,7 +631,7 @@ impl ActionTree { actions.push(Action::Check); // bet - for &bet_size in &bet_options[player as usize].bet { + for &bet_size in bet_options[player as usize].bets() { match bet_size { BetSize::PotRelative(ratio) => { let amount = (pot as f64 * ratio).round() as i32; @@ -664,7 +664,7 @@ impl ActionTree { if !info.allin_flag { // raise - for &bet_size in &bet_options[player as usize].raise { + for &bet_size in bet_options[player as usize].raises() { match bet_size { BetSize::PotRelative(ratio) => { let amount = prev_amount + (pot as f64 * ratio).round() as i32; diff --git a/src/bet_size.rs b/src/bet_size.rs index 7830ffa..1c2596e 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -27,7 +27,7 @@ use serde::{Deserialize, Serialize}; /// let bet_size = BetSizeOptions::try_from(("50%, 100c, 2e, a", "2.5x")).unwrap(); /// /// assert_eq!( -/// bet_size.bet, +/// bet_size.bets(), /// vec![ /// PotRelative(0.5), /// Additive(100, 0), @@ -36,16 +36,16 @@ use serde::{Deserialize, Serialize}; /// ] /// ); /// -/// assert_eq!(bet_size.raise, vec![PrevBetRelative(2.5)]); +/// assert_eq!(bet_size.raises(), vec![PrevBetRelative(2.5)]); /// ``` #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct BetSizeOptions { /// Bet size options for first bet. - pub bet: Vec, + bet: Vec, /// Bet size options for raise. - pub raise: Vec, + raise: Vec, } /// Bet size options for the donk bets. @@ -81,6 +81,55 @@ pub enum BetSize { AllIn, } +impl BetSizeOptions { + /// Tries to create a `BetSizeOptions` from two `BetSize` vecs. + /// + /// # Errors + /// + /// Returns `Err` when: + /// - `bets` contains a `BetSize::Relative` bet size + /// - `bets` contains an `BetSize::Additive(_, cap)` with non-zero `cap` + pub fn try_from_sizes(bets: Vec, raises: Vec) -> Result { + Ok(BetSizeOptions { + bet: BetSizeOptions::as_valid_bets(bets)?, + raise: raises, + }) + } + + /// Check `bets` for well-formedness (no sizes relative to previous bet and + /// no raise caps) and return it. Return an `Err` if: + /// - `bets` contains a `BetSize::Relative` bet size + /// - `bets` contains an `BetSize::Additive(_, cap)` with non-zero `cap` + pub fn as_valid_bets(bets: Vec) -> Result, String> { + for bs in bets.iter() { + match &bs { + BetSize::PrevBetRelative(_) => { + let err_msg = "bets cannot contain `BetSize::PrevBetRelative".to_string(); + return Err(err_msg); + } + BetSize::Additive(_, cap) => { + if cap != &0 { + let err_msg = + "bets cannot contain additive bet sizes with non-zero raise caps" + .to_string(); + return Err(err_msg); + } + } + _ => (), + } + } + Ok(bets) + } + + pub fn bets(&self) -> &[BetSize] { + &self.bet + } + + pub fn raises(&self) -> &[BetSize] { + &self.raise + } +} + impl TryFrom<(&str, &str)> for BetSizeOptions { type Error = String; @@ -103,17 +152,19 @@ impl TryFrom<(&str, &str)> for BetSizeOptions { let mut raise = Vec::new(); for bet_size in bet_sizes { - bet.push(bet_size_from_str(bet_size, false)?); + bet.push(bet_size_from_str(bet_size)?); } for raise_size in raise_sizes { - raise.push(bet_size_from_str(raise_size, true)?); + raise.push(bet_size_from_str(raise_size)?); } + // Check for ill-formed bet sizes. This includes + // - bet sizes with relative amounts (e.g., "3x") bet.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); raise.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); - Ok(BetSizeOptions { bet, raise }) + Self::try_from_sizes(bet, raise) } } @@ -133,12 +184,14 @@ impl TryFrom<&str> for DonkSizeOptions { let mut donk = Vec::new(); for donk_size in donk_sizes { - donk.push(bet_size_from_str(donk_size, false)?); + donk.push(bet_size_from_str(donk_size)?); } donk.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); - Ok(DonkSizeOptions { donk }) + Ok(DonkSizeOptions { + donk: BetSizeOptions::as_valid_bets(donk)?, + }) } } @@ -150,23 +203,18 @@ fn parse_float(s: &str) -> Option { } } -fn bet_size_from_str(s: &str, is_raise: bool) -> Result { +fn bet_size_from_str(s: &str) -> Result { let s_lower = s.to_lowercase(); let err_msg = format!("Invalid bet size: {s}"); if let Some(prev_bet_rel) = s_lower.strip_suffix('x') { // Previous bet relative - if !is_raise { - let err_msg = format!("Relative size to the previous bet is not allowed: {s}"); + let float = parse_float(prev_bet_rel).ok_or(&err_msg)?; + if float <= 1.0 { + let err_msg = format!("Multiplier must be greater than 1.0: {s}"); Err(err_msg) } else { - let float = parse_float(prev_bet_rel).ok_or(&err_msg)?; - if float <= 1.0 { - let err_msg = format!("Multiplier must be greater than 1.0: {s}"); - Err(err_msg) - } else { - Ok(BetSize::PrevBetRelative(float)) - } + Ok(BetSize::PrevBetRelative(float)) } } else if s_lower.contains('c') { // Additive @@ -185,10 +233,6 @@ fn bet_size_from_str(s: &str, is_raise: bool) -> Result { let cap = if cap_str.is_empty() { 0 } else { - if !is_raise { - let err_msg = format!("Raise cap is not allowed: {s}"); - return Err(err_msg); - } let float_str = cap_str.strip_suffix('r').ok_or(&err_msg)?; let float = parse_float(float_str).ok_or(&err_msg)?; if float.trunc() != float || float == 0.0 { @@ -278,18 +322,18 @@ mod tests { ]; for (s, expected) in tests { - assert_eq!(bet_size_from_str(s, true), Ok(expected)); + assert_eq!(bet_size_from_str(s), Ok(expected)); } - let error_tests = [ - "", "0", "1.23", "%", "+42%", "-30%", "x", "0x", "1x", "c", "12.3c", "10c10", "42cr", - "c3r", "0c0r", "123c101r", "1c2r3", "12c3.4r", "0e", "2.7e", "101e", "3e7", "E%", - "1e2e3", "bet", "1a", "a1", - ]; + // let error_tests = [ + // "", "0", "1.23", "%", "+42%", "-30%", "x", "0x", "1x", "c", "12.3c", "10c10", "42cr", + // "c3r", "0c0r", "123c101r", "1c2r3", "12c3.4r", "0e", "2.7e", "101e", "3e7", "E%", + // "1e2e3", "bet", "1a", "a1", + // ]; - for s in error_tests { - assert!(bet_size_from_str(s, true).is_err()); - } + // for s in error_tests { + // assert!(bet_size_from_str(s, true).is_err()); + // } } #[test] @@ -298,18 +342,20 @@ mod tests { ( "40%, 70%", "", - BetSizeOptions { - bet: vec![PotRelative(0.4), PotRelative(0.7)], - raise: Vec::new(), - }, + BetSizeOptions::try_from_sizes( + vec![PotRelative(0.4), PotRelative(0.7)], + Vec::new(), + ) + .unwrap(), ), ( "50c, e, a,", "25%, 2.5x, e200%", - BetSizeOptions { - bet: vec![Additive(50, 0), Geometric(0, f64::INFINITY), AllIn], - raise: vec![PotRelative(0.25), PrevBetRelative(2.5), Geometric(0, 2.0)], - }, + BetSizeOptions::try_from_sizes( + vec![Additive(50, 0), Geometric(0, f64::INFINITY), AllIn], + vec![PotRelative(0.25), PrevBetRelative(2.5), Geometric(0, 2.0)], + ) + .unwrap(), ), ]; From a2158ff417ab29a773b339dbfcad714e486852c6 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:30:32 -0400 Subject: [PATCH 2/9] Removed old comment --- src/bet_size.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index 1c2596e..d1558f7 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -158,8 +158,6 @@ impl TryFrom<(&str, &str)> for BetSizeOptions { for raise_size in raise_sizes { raise.push(bet_size_from_str(raise_size)?); } - // Check for ill-formed bet sizes. This includes - // - bet sizes with relative amounts (e.g., "3x") bet.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); raise.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); From 20d0dc3cbe347bf442a8bc1dc7d1e5d9940f7228 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:36:11 -0400 Subject: [PATCH 3/9] Made DonkSizeOptions non-public --- src/action_tree.rs | 2 +- src/bet_size.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/action_tree.rs b/src/action_tree.rs index 27b520a..f99f189 100644 --- a/src/action_tree.rs +++ b/src/action_tree.rs @@ -599,7 +599,7 @@ impl ActionTree { actions.push(Action::Check); // donk bet - for &donk_size in &donk_options.as_ref().unwrap().donk { + for &donk_size in donk_options.as_ref().unwrap().donks() { match donk_size { BetSize::PotRelative(ratio) => { let amount = (pot as f64 * ratio).round() as i32; diff --git a/src/bet_size.rs b/src/bet_size.rs index d1558f7..a5f26c8 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -54,7 +54,7 @@ pub struct BetSizeOptions { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct DonkSizeOptions { - pub donk: Vec, + donk: Vec, } /// Bet size specification. @@ -166,6 +166,12 @@ impl TryFrom<(&str, &str)> for BetSizeOptions { } } +impl DonkSizeOptions { + pub fn donks(&self) -> &[BetSize] { + &self.donk + } +} + impl TryFrom<&str> for DonkSizeOptions { type Error = String; From 78597fef3aa9d18bdc88ddfa3d5482b927604547 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:37:13 -0400 Subject: [PATCH 4/9] Pluralized BetSizeOptions and DonkOptions field names --- src/bet_size.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index a5f26c8..70a04f1 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -42,10 +42,10 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct BetSizeOptions { /// Bet size options for first bet. - bet: Vec, + bets: Vec, /// Bet size options for raise. - raise: Vec, + raises: Vec, } /// Bet size options for the donk bets. @@ -91,8 +91,8 @@ impl BetSizeOptions { /// - `bets` contains an `BetSize::Additive(_, cap)` with non-zero `cap` pub fn try_from_sizes(bets: Vec, raises: Vec) -> Result { Ok(BetSizeOptions { - bet: BetSizeOptions::as_valid_bets(bets)?, - raise: raises, + bets: BetSizeOptions::as_valid_bets(bets)?, + raises, }) } @@ -122,11 +122,11 @@ impl BetSizeOptions { } pub fn bets(&self) -> &[BetSize] { - &self.bet + &self.bets } pub fn raises(&self) -> &[BetSize] { - &self.raise + &self.raises } } From 245df956c461cdf9f492c840b0a924635cee26e4 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:38:42 -0400 Subject: [PATCH 5/9] Finished renaming fields --- src/bet_size.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index 70a04f1..7fc0f89 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -54,7 +54,7 @@ pub struct BetSizeOptions { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct DonkSizeOptions { - donk: Vec, + donks: Vec, } /// Bet size specification. @@ -168,7 +168,7 @@ impl TryFrom<(&str, &str)> for BetSizeOptions { impl DonkSizeOptions { pub fn donks(&self) -> &[BetSize] { - &self.donk + &self.donks } } @@ -194,7 +194,7 @@ impl TryFrom<&str> for DonkSizeOptions { donk.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); Ok(DonkSizeOptions { - donk: BetSizeOptions::as_valid_bets(donk)?, + donks: BetSizeOptions::as_valid_bets(donk)?, }) } } @@ -380,13 +380,13 @@ mod tests { ( "40%, 70%", DonkSizeOptions { - donk: vec![PotRelative(0.4), PotRelative(0.7)], + donks: vec![PotRelative(0.4), PotRelative(0.7)], }, ), ( "50c, e, a,", DonkSizeOptions { - donk: vec![Additive(50, 0), Geometric(0, f64::INFINITY), AllIn], + donks: vec![Additive(50, 0), Geometric(0, f64::INFINITY), AllIn], }, ), ]; From 40df53bd4febbb2ef198731add15a49c48757512 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Sun, 13 Oct 2024 15:41:32 -0400 Subject: [PATCH 6/9] Uncommented err test --- src/bet_size.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index 7fc0f89..4e95b68 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -329,15 +329,15 @@ mod tests { assert_eq!(bet_size_from_str(s), Ok(expected)); } - // let error_tests = [ - // "", "0", "1.23", "%", "+42%", "-30%", "x", "0x", "1x", "c", "12.3c", "10c10", "42cr", - // "c3r", "0c0r", "123c101r", "1c2r3", "12c3.4r", "0e", "2.7e", "101e", "3e7", "E%", - // "1e2e3", "bet", "1a", "a1", - // ]; - - // for s in error_tests { - // assert!(bet_size_from_str(s, true).is_err()); - // } + let error_tests = [ + "", "0", "1.23", "%", "+42%", "-30%", "x", "0x", "1x", "c", "12.3c", "10c10", "42cr", + "c3r", "0c0r", "123c101r", "1c2r3", "12c3.4r", "0e", "2.7e", "101e", "3e7", "E%", + "1e2e3", "bet", "1a", "a1", + ]; + + for s in error_tests { + assert!(bet_size_from_str(s).is_err()); + } } #[test] From 3a80ad619fdca3b3457b46bb7718bad0d239efc1 Mon Sep 17 00:00:00 2001 From: bkushigian Date: Mon, 14 Oct 2024 12:40:05 -0400 Subject: [PATCH 7/9] Got a compiling serilize/deserialize bet size --- src/bet_size.rs | 132 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index 4e95b68..f0ba5bf 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -1,6 +1,6 @@ #[cfg(feature = "bincode")] use bincode::{Decode, Encode}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Bet size options for the first bets and raises. /// @@ -42,9 +42,13 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct BetSizeOptions { /// Bet size options for first bet. + #[serde(deserialize_with = "deserialize_bet_sizes", default)] + #[serde(serialize_with = "serialize_bet_sizes")] bets: Vec, /// Bet size options for raise. + #[serde(deserialize_with = "deserialize_bet_sizes", default)] + #[serde(serialize_with = "serialize_bet_sizes")] raises: Vec, } @@ -54,12 +58,15 @@ pub struct BetSizeOptions { #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bincode", derive(Decode, Encode))] pub struct DonkSizeOptions { + #[serde(deserialize_with = "deserialize_bet_sizes", default)] + #[serde(serialize_with = "serialize_bet_sizes")] donks: Vec, } /// Bet size specification. #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)] #[cfg_attr(feature = "bincode", derive(Decode, Encode))] +#[serde(try_from = "&str")] pub enum BetSize { /// Bet size relative to the current pot size. PotRelative(f64), @@ -130,6 +137,14 @@ impl BetSizeOptions { } } +impl TryFrom<&str> for BetSize { + type Error = String; + + fn try_from(s: &str) -> Result { + bet_size_from_str(s) + } +} + impl TryFrom<(&str, &str)> for BetSizeOptions { type Error = String; @@ -137,32 +152,7 @@ impl TryFrom<(&str, &str)> for BetSizeOptions { /// /// See the [`BetSizeOptions`] struct for the description and examples. fn try_from((bet_str, raise_str): (&str, &str)) -> Result { - let mut bet_sizes = bet_str.split(',').map(str::trim).collect::>(); - let mut raise_sizes = raise_str.split(',').map(str::trim).collect::>(); - - if bet_sizes.last().unwrap().is_empty() { - bet_sizes.pop(); - } - - if raise_sizes.last().unwrap().is_empty() { - raise_sizes.pop(); - } - - let mut bet = Vec::new(); - let mut raise = Vec::new(); - - for bet_size in bet_sizes { - bet.push(bet_size_from_str(bet_size)?); - } - - for raise_size in raise_sizes { - raise.push(bet_size_from_str(raise_size)?); - } - - bet.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); - raise.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); - - Self::try_from_sizes(bet, raise) + Self::try_from_sizes(bet_sizes_from_str(bet_str)?, bet_sizes_from_str(raise_str)?) } } @@ -179,23 +169,39 @@ impl TryFrom<&str> for DonkSizeOptions { /// /// See the [`BetSizeOptions`] struct for the description and examples. fn try_from(donk_str: &str) -> Result { - let mut donk_sizes = donk_str.split(',').map(str::trim).collect::>(); - - if donk_sizes.last().unwrap().is_empty() { - donk_sizes.pop(); - } - - let mut donk = Vec::new(); + let donks = bet_sizes_from_str(donk_str)?; + let donks = BetSizeOptions::as_valid_bets(donks)?; + Ok(DonkSizeOptions { donks }) + } +} - for donk_size in donk_sizes { - donk.push(bet_size_from_str(donk_size)?); +impl From for String { + fn from(bet_size: BetSize) -> Self { + match bet_size { + BetSize::PotRelative(x) => format!("{}%", x), + BetSize::PrevBetRelative(x) => format!("{}x", x), + BetSize::Additive(c, r) => { + if r != 0 { + format!("{}c{}r", c, r) + } else { + format!("{}c", c) + } + } + BetSize::Geometric(n, r) => { + if n == 0 { + if r == f64::INFINITY { + "e".to_string() + } else { + format!("e{}", r * 100.0) + } + } else if r == f64::INFINITY { + format!("{}e", n) + } else { + format!("{}e{}", n, r) + } + } + BetSize::AllIn => "a".to_string(), } - - donk.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); - - Ok(DonkSizeOptions { - donks: BetSizeOptions::as_valid_bets(donk)?, - }) } } @@ -207,6 +213,31 @@ fn parse_float(s: &str) -> Option { } } +fn bet_sizes_from_str(bets_str: &str) -> Result, String> { + let mut bet_sizes = bets_str.split(',').map(str::trim).collect::>(); + + if bet_sizes.last().unwrap().is_empty() { + bet_sizes.pop(); + } + + let mut bets = Vec::new(); + + for bet_size in bet_sizes { + bets.push(bet_size_from_str(bet_size)?); + } + + bets.sort_unstable_by(|l, r| l.partial_cmp(r).unwrap()); + + Ok(bets) +} + +fn deserialize_bet_sizes<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + Vec::::deserialize(deserializer) +} + fn bet_size_from_str(s: &str) -> Result { let s_lower = s.to_lowercase(); let err_msg = format!("Invalid bet size: {s}"); @@ -299,6 +330,23 @@ fn bet_size_from_str(s: &str) -> Result { } } +pub fn bet_size_to_string(bs: &BetSize) -> String { + String::from(*bs) +} + +pub fn serialize_bet_sizes(bs: &[BetSize], s: S) -> Result +where + S: Serializer, +{ + s.serialize_str( + bs.iter() + .map(|b| String::from(*b)) + .collect::>() + .join(",") + .as_str(), + ) +} + #[cfg(test)] mod tests { use super::BetSize::*; From f1142c845f9e8a09a5eb9e6218d6a8cb1dcda69d Mon Sep 17 00:00:00 2001 From: bkushigian Date: Mon, 14 Oct 2024 21:31:30 -0400 Subject: [PATCH 8/9] Serialization and deserialization works --- src/bet_size.rs | 8 +++++--- src/game/base.rs | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/bet_size.rs b/src/bet_size.rs index f0ba5bf..50d1739 100644 --- a/src/bet_size.rs +++ b/src/bet_size.rs @@ -1,6 +1,6 @@ #[cfg(feature = "bincode")] use bincode::{Decode, Encode}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; /// Bet size options for the first bets and raises. /// @@ -178,7 +178,7 @@ impl TryFrom<&str> for DonkSizeOptions { impl From for String { fn from(bet_size: BetSize) -> Self { match bet_size { - BetSize::PotRelative(x) => format!("{}%", x), + BetSize::PotRelative(x) => format!("{}%", 100.0 * x), BetSize::PrevBetRelative(x) => format!("{}x", x), BetSize::Additive(c, r) => { if r != 0 { @@ -235,7 +235,9 @@ fn deserialize_bet_sizes<'de, D>(deserializer: D) -> Result, D::Err where D: Deserializer<'de>, { - Vec::::deserialize(deserializer) + let s = String::deserialize(deserializer)?; + let bet_sizes = bet_sizes_from_str(&s); + bet_sizes.map_err(de::Error::custom) } fn bet_size_from_str(s: &str) -> Result { diff --git a/src/game/base.rs b/src/game/base.rs index e657bfb..f5282ec 100644 --- a/src/game/base.rs +++ b/src/game/base.rs @@ -1488,7 +1488,9 @@ impl PostFlopGame { Ok(json_config) } - pub fn game_from_configs_json(configs_json: serde_json::Value) -> Result { + pub fn game_from_configs_json( + configs_json: &serde_json::Value, + ) -> Result { let map = configs_json.as_object().ok_or({ "Config JSON must be a JSON object with keys \"tree_config\" and \"card_config\"" })?; @@ -1499,9 +1501,9 @@ impl PostFlopGame { .get("card_config") .ok_or("Config JSON must contain key \"card_config\"")?; let tree_config: TreeConfig = serde_json::from_value(tree_config.clone()) - .map_err(|_| "Error deserializing tree_config")?; + .map_err(|e| format!("Error deserializing tree_config: {:?}", e))?; let card_config: CardConfig = serde_json::from_value(card_config.clone()) - .map_err(|_| "Error deserializing card_config")?; + .map_err(|e| format!("Error deserializing card_config: {:?}", e))?; let action_tree = ActionTree::new(tree_config)?; PostFlopGame::with_config(card_config, action_tree) } From 003668efd062727f20382d6ba429169871346d4a Mon Sep 17 00:00:00 2001 From: bkushigian Date: Wed, 16 Oct 2024 07:15:40 -0400 Subject: [PATCH 9/9] Clippyw orkaround --- src/range.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/range.rs b/src/range.rs index eac5953..71f0833 100644 --- a/src/range.rs +++ b/src/range.rs @@ -993,6 +993,8 @@ impl<'de> Deserialize<'de> for Range { { struct RangeVisitor; + // A workaround in a clippy bug + #[allow(clippy::needless_lifetimes)] impl<'de> Visitor<'de> for RangeVisitor { type Value = Range;