refactor(core): unify Suit/Rank with card_game upstream types
Build and Deploy / build-and-push (push) Failing after 56s
Web E2E / web-e2e (push) Failing after 4m23s

Replace the parallel solitaire_core::Suit and solitaire_core::Rank
definitions with pub-use re-exports from card_game. card_game upstream
gained serde, is_black(), and value() to make this clean.

- card.rs: remove Suit/Rank enums and impls; add pub use card_game::{Suit,Rank}
- klondike_adapter.rs: remove From<card_game::Suit/Rank> bridges (now same type)
- Simplify card_from_kl: .into() calls become direct assignment
- Cargo.toml: switch to git deps (serde feature), Cargo.lock updated

All 62 solitaire_core tests pass; clippy clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-08 10:57:49 -07:00
parent 5e8735886f
commit ae1ecc8559
4 changed files with 71 additions and 140 deletions
Generated
+66 -6
View File
@@ -2084,10 +2084,10 @@ dependencies = [
[[package]] [[package]]
name = "card_game" name = "card_game"
version = "0.4.0" version = "0.4.0"
source = "sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/" source = "git+https://git.aleshym.co/Quaternions/card_game#2eaa99e82dc40ab59ca0033717667fe7f66452d3"
checksum = "d206df6d87340019a0f5b621976cf98bc75c659a7f93ef348aaab2a9336098a9"
dependencies = [ dependencies = [
"arrayvec 0.7.6 (sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/)", "arrayvec 0.7.6 (sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/)",
"serde",
] ]
[[package]] [[package]]
@@ -4305,7 +4305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
dependencies = [ dependencies = [
"byteorder-lite", "byteorder-lite",
"quick-error", "quick-error 2.0.1",
] ]
[[package]] [[package]]
@@ -4600,8 +4600,7 @@ dependencies = [
[[package]] [[package]]
name = "klondike" name = "klondike"
version = "0.3.0" version = "0.3.0"
source = "sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/" source = "git+https://git.aleshym.co/Quaternions/card_game#2eaa99e82dc40ab59ca0033717667fe7f66452d3"
checksum = "347d55e6cf7c90b3d038262071eb2fdb0b75a713fe66c452a3400ff08fb716bc"
dependencies = [ dependencies = [
"card_game", "card_game",
"rand 0.10.1", "rand 0.10.1",
@@ -6059,6 +6058,25 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
[[package]]
name = "proptest"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
dependencies = [
"bit-set",
"bit-vec",
"bitflags 2.11.1",
"num-traits",
"rand 0.9.4",
"rand_chacha 0.9.0",
"rand_xorshift",
"regex-syntax",
"rusty-fork",
"tempfile",
"unarray",
]
[[package]] [[package]]
name = "prost" name = "prost"
version = "0.14.3" version = "0.14.3"
@@ -6103,6 +6121,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]] [[package]]
name = "quick-error" name = "quick-error"
version = "2.0.1" version = "2.0.1"
@@ -6301,6 +6325,15 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
[[package]]
name = "rand_xorshift"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
dependencies = [
"rand_core 0.9.5",
]
[[package]] [[package]]
name = "range-alloc" name = "range-alloc"
version = "0.1.5" version = "0.1.5"
@@ -6790,6 +6823,18 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "rusty-fork"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2"
dependencies = [
"fnv",
"quick-error 1.2.3",
"tempfile",
"wait-timeout",
]
[[package]] [[package]]
name = "rustybuzz" name = "rustybuzz"
version = "0.20.1" version = "0.20.1"
@@ -7279,6 +7324,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"card_game", "card_game",
"klondike", "klondike",
"proptest",
"serde", "serde",
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
@@ -7289,7 +7335,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"bevy",
"chrono", "chrono",
"dirs", "dirs",
"jni 0.21.1", "jni 0.21.1",
@@ -8846,6 +8891,12 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]] [[package]]
name = "uncased" name = "uncased"
version = "0.9.10" version = "0.9.10"
@@ -9052,6 +9103,15 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wait-timeout"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.5.0" version = "2.5.0"
+2 -2
View File
@@ -38,8 +38,8 @@ solitaire_core = { path = "solitaire_core" }
solitaire_sync = { path = "solitaire_sync" } solitaire_sync = { path = "solitaire_sync" }
solitaire_data = { path = "solitaire_data" } solitaire_data = { path = "solitaire_data" }
solitaire_engine = { path = "solitaire_engine" } solitaire_engine = { path = "solitaire_engine" }
klondike = { version = "0.3.0", registry = "Quaternions" } klondike = { git = "https://git.aleshym.co/Quaternions/card_game" }
card_game = { version = "0.4.0", registry = "Quaternions" } card_game = { git = "https://git.aleshym.co/Quaternions/card_game", features = ["serde"] }
# Bevy with `default-features = false` to avoid the unused # Bevy with `default-features = false` to avoid the unused
# `bevy_audio → rodio + symphonia + cpal 0.15 + alsa 0.9` chain. # `bevy_audio → rodio + symphonia + cpal 0.15 + alsa 0.9` chain.
+1 -97
View File
@@ -1,102 +1,6 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Card suit. pub use card_game::{Rank, Suit};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Suit {
Clubs,
Diamonds,
Hearts,
Spades,
}
impl Suit {
/// All four suits in declaration order.
pub const SUITS: [Self; 4] = [Self::Clubs, Self::Diamonds, Self::Hearts, Self::Spades];
/// Returns `true` for red suits (Diamonds, Hearts).
pub fn is_red(self) -> bool {
matches!(self, Suit::Diamonds | Suit::Hearts)
}
/// Returns `true` for black suits (Clubs, Spades).
pub fn is_black(self) -> bool {
!self.is_red()
}
}
/// Card rank, Ace through King.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Rank {
Ace = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Jack = 11,
Queen = 12,
King = 13,
}
impl Rank {
/// All thirteen ranks in ascending order.
pub const RANKS: [Self; 13] = [
Self::Ace,
Self::Two,
Self::Three,
Self::Four,
Self::Five,
Self::Six,
Self::Seven,
Self::Eight,
Self::Nine,
Self::Ten,
Self::Jack,
Self::Queen,
Self::King,
];
/// Numeric value: Ace = 1, King = 13.
pub fn value(self) -> u8 {
self as u8
}
const fn new(n: u8) -> Option<Self> {
match n {
1 => Some(Self::Ace),
2 => Some(Self::Two),
3 => Some(Self::Three),
4 => Some(Self::Four),
5 => Some(Self::Five),
6 => Some(Self::Six),
7 => Some(Self::Seven),
8 => Some(Self::Eight),
9 => Some(Self::Nine),
10 => Some(Self::Ten),
11 => Some(Self::Jack),
12 => Some(Self::Queen),
13 => Some(Self::King),
_ => None,
}
}
/// Returns the rank `n` steps above `self`, or `None` if it would exceed King.
pub const fn checked_add(self, n: u8) -> Option<Self> {
Self::new((self as u8).saturating_add(n))
}
/// Returns the rank `n` steps below `self`, or `None` if it would go below Ace.
pub const fn checked_sub(self, n: u8) -> Option<Self> {
match (self as u8).checked_sub(n) {
Some(v) => Self::new(v),
None => None,
}
}
}
/// A single playing card. /// A single playing card.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+2 -35
View File
@@ -156,39 +156,6 @@ impl KlondikeAdapter {
} }
} }
// ── Type-conversion utilities ─────────────────────────────────────────────
impl From<card_game::Suit> for card::Suit {
fn from(s: card_game::Suit) -> Self {
match s {
card_game::Suit::Clubs => Self::Clubs,
card_game::Suit::Diamonds => Self::Diamonds,
card_game::Suit::Hearts => Self::Hearts,
card_game::Suit::Spades => Self::Spades,
}
}
}
impl From<card_game::Rank> for card::Rank {
fn from(r: card_game::Rank) -> Self {
match r {
card_game::Rank::Ace => Self::Ace,
card_game::Rank::Two => Self::Two,
card_game::Rank::Three => Self::Three,
card_game::Rank::Four => Self::Four,
card_game::Rank::Five => Self::Five,
card_game::Rank::Six => Self::Six,
card_game::Rank::Seven => Self::Seven,
card_game::Rank::Eight => Self::Eight,
card_game::Rank::Nine => Self::Nine,
card_game::Rank::Ten => Self::Ten,
card_game::Rank::Jack => Self::Jack,
card_game::Rank::Queen => Self::Queen,
card_game::Rank::King => Self::King,
}
}
}
/// Convert a zero-based tableau index (0..=6) into [`Tableau`]. /// Convert a zero-based tableau index (0..=6) into [`Tableau`].
pub fn tableau_from_index(index: usize) -> Option<Tableau> { pub fn tableau_from_index(index: usize) -> Option<Tableau> {
match index { match index {
@@ -239,8 +206,8 @@ pub fn skip_cards_from_count(skip: usize) -> Option<SkipCards> {
/// ///
/// The id is consistent for the same logical card across all reconstructions. /// The id is consistent for the same logical card across all reconstructions.
pub fn card_from_kl(kl_card: &KlCard) -> card::Card { pub fn card_from_kl(kl_card: &KlCard) -> card::Card {
let suit: card::Suit = kl_card.suit().into(); let suit = kl_card.suit();
let rank: card::Rank = kl_card.rank().into(); let rank = kl_card.rank();
let suit_index = match suit { let suit_index = match suit {
card::Suit::Clubs => 0, card::Suit::Clubs => 0,
card::Suit::Diamonds => 1, card::Suit::Diamonds => 1,