From c06451156ee2d9272d97a26570856802dfd4f813 Mon Sep 17 00:00:00 2001 From: Rhys Lloyd Date: Mon, 8 Jun 2026 23:00:15 -0700 Subject: [PATCH] klondike serde --- Cargo.lock | 2 ++ klondike/Cargo.toml | 6 ++++++ klondike/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f91f9e5..f30e0af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,6 +132,8 @@ version = "0.3.0" dependencies = [ "card_game", "rand", + "serde", + "serde_derive", ] [[package]] diff --git a/klondike/Cargo.toml b/klondike/Cargo.toml index 1c55cb4..557c118 100644 --- a/klondike/Cargo.toml +++ b/klondike/Cargo.toml @@ -6,6 +6,12 @@ edition = "2024" [dependencies] card_game.workspace = true rand = { version = "0.10.1", default-features = false, features = ["std_rng"] } +serde = { version = "1.0.228", default-features = false, optional = true } +serde_derive = { version = "1.0.228", default-features = false, optional = true } [lints] workspace = true + +[features] +default = ["serde"] +serde = ["dep:serde", "dep:serde_derive"] diff --git a/klondike/src/lib.rs b/klondike/src/lib.rs index 48b491d..922b52a 100644 --- a/klondike/src/lib.rs +++ b/klondike/src/lib.rs @@ -7,6 +7,10 @@ use card_game::{Card, Game, Pile, Rank, Stack}; #[cfg(doctest)] struct ReadmeDoctests; +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub enum DrawStockConfig { #[default] @@ -14,6 +18,10 @@ pub enum DrawStockConfig { DrawThree = 3, } +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub enum MoveFromFoundationConfig { #[default] @@ -21,6 +29,10 @@ pub enum MoveFromFoundationConfig { Disallowed, } +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Copy, Debug)] pub struct ScoringConfig { pub move_to_foundation: i32, @@ -44,6 +56,10 @@ impl Default for ScoringConfig { } } +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Debug, Default)] pub struct KlondikeConfig { pub draw_stock: DrawStockConfig, @@ -379,6 +395,10 @@ const fn sum(n: usize) -> usize { const STOCK: usize = 52 - sum(TABLEAUS); const NUM_RANKS: usize = Rank::RANKS.len(); +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct KlondikeState { stock: Pile, @@ -613,6 +633,10 @@ fn test_klondike_iter() { assert_eq!(KlondikeIter::new().count(), 721); } +#[cfg_attr( + feature = "serde", + derive(serde_derive::Deserialize, serde_derive::Serialize) +)] #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Klondike { state: KlondikeState, @@ -797,3 +821,28 @@ impl Game for Klondike { }) } } + +#[cfg(feature = "serde")] +impl serde::Serialize for KlondikeInstruction { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // There is 721 klondike instructions + let instruction_id = KlondikeIter::new() + .position(|instruction| &instruction == self) + .unwrap(); + serializer.serialize_u16(instruction_id as u16) + } +} +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for KlondikeInstruction { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let instruction_id = u16::deserialize(deserializer)?; + let instruction = KlondikeIter::new().nth(instruction_id as usize).unwrap(); + Ok(instruction) + } +}