refactor(core): unify Suit/Rank with card_game upstream types
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:
Generated
+66
-6
@@ -2084,10 +2084,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "card_game"
|
||||
version = "0.4.0"
|
||||
source = "sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/"
|
||||
checksum = "d206df6d87340019a0f5b621976cf98bc75c659a7f93ef348aaab2a9336098a9"
|
||||
source = "git+https://git.aleshym.co/Quaternions/card_game#2eaa99e82dc40ab59ca0033717667fe7f66452d3"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.6 (sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/)",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4305,7 +4305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
|
||||
dependencies = [
|
||||
"byteorder-lite",
|
||||
"quick-error",
|
||||
"quick-error 2.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4600,8 +4600,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "klondike"
|
||||
version = "0.3.0"
|
||||
source = "sparse+https://git.aleshym.co/api/packages/Quaternions/cargo/"
|
||||
checksum = "347d55e6cf7c90b3d038262071eb2fdb0b75a713fe66c452a3400ff08fb716bc"
|
||||
source = "git+https://git.aleshym.co/Quaternions/card_game#2eaa99e82dc40ab59ca0033717667fe7f66452d3"
|
||||
dependencies = [
|
||||
"card_game",
|
||||
"rand 0.10.1",
|
||||
@@ -6059,6 +6058,25 @@ version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "prost"
|
||||
version = "0.14.3"
|
||||
@@ -6103,6 +6121,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "2.0.1"
|
||||
@@ -6301,6 +6325,15 @@ dependencies = [
|
||||
"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]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.5"
|
||||
@@ -6790,6 +6823,18 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "rustybuzz"
|
||||
version = "0.20.1"
|
||||
@@ -7279,6 +7324,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"card_game",
|
||||
"klondike",
|
||||
"proptest",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
@@ -7289,7 +7335,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"bevy",
|
||||
"chrono",
|
||||
"dirs",
|
||||
"jni 0.21.1",
|
||||
@@ -8846,6 +8891,12 @@ dependencies = [
|
||||
"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]]
|
||||
name = "uncased"
|
||||
version = "0.9.10"
|
||||
@@ -9052,6 +9103,15 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
|
||||
+2
-2
@@ -38,8 +38,8 @@ solitaire_core = { path = "solitaire_core" }
|
||||
solitaire_sync = { path = "solitaire_sync" }
|
||||
solitaire_data = { path = "solitaire_data" }
|
||||
solitaire_engine = { path = "solitaire_engine" }
|
||||
klondike = { version = "0.3.0", registry = "Quaternions" }
|
||||
card_game = { version = "0.4.0", registry = "Quaternions" }
|
||||
klondike = { git = "https://git.aleshym.co/Quaternions/card_game" }
|
||||
card_game = { git = "https://git.aleshym.co/Quaternions/card_game", features = ["serde"] }
|
||||
|
||||
# Bevy with `default-features = false` to avoid the unused
|
||||
# `bevy_audio → rodio + symphonia + cpal 0.15 + alsa 0.9` chain.
|
||||
|
||||
@@ -1,102 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Card 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use card_game::{Rank, Suit};
|
||||
|
||||
/// A single playing card.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
|
||||
@@ -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`].
|
||||
pub fn tableau_from_index(index: usize) -> Option<Tableau> {
|
||||
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.
|
||||
pub fn card_from_kl(kl_card: &KlCard) -> card::Card {
|
||||
let suit: card::Suit = kl_card.suit().into();
|
||||
let rank: card::Rank = kl_card.rank().into();
|
||||
let suit = kl_card.suit();
|
||||
let rank = kl_card.rank();
|
||||
let suit_index = match suit {
|
||||
card::Suit::Clubs => 0,
|
||||
card::Suit::Diamonds => 1,
|
||||
|
||||
Reference in New Issue
Block a user