fix(core,sync,data): deterministic pile serialization, undo skip, url-encode bytes, merge_at
- Derive PartialOrd+Ord on PileType and sort pile entries in pile_map_serde before serializing so save-file output is deterministic (M-4) - Add #[serde(skip)] to undo_stack so transient undo history is never written to save files, eliminating unnecessary bloat (M-3) - Add merge_at() accepting an explicit resolved_at timestamp so callers can inject the server-side time; merge() wraps it with Utc::now() for backwards compatibility (M-1) - Fix url_encode to percent-encode UTF-8 bytes rather than Unicode codepoints so multi-byte characters produce RFC 3986-compliant output (M-2) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,8 @@ mod pile_map_serde {
|
||||
use crate::pile::{Pile, PileType};
|
||||
|
||||
pub fn serialize<S: Serializer>(map: &HashMap<PileType, Pile>, s: S) -> Result<S::Ok, S::Error> {
|
||||
let entries: Vec<(&PileType, &Pile)> = map.iter().collect();
|
||||
let mut entries: Vec<(&PileType, &Pile)> = map.iter().collect();
|
||||
entries.sort_by_key(|(k, _)| *k);
|
||||
entries.serialize(s)
|
||||
}
|
||||
|
||||
@@ -154,6 +155,7 @@ pub struct GameState {
|
||||
/// [`GAME_STATE_SCHEMA_VERSION`].
|
||||
#[serde(default = "schema_v1")]
|
||||
pub schema_version: u32,
|
||||
#[serde(skip)]
|
||||
undo_stack: VecDeque<StateSnapshot>,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::card::{Card, Suit};
|
||||
|
||||
/// Identifies which pile on the board a set of cards belongs to.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
pub enum PileType {
|
||||
/// The face-down draw pile.
|
||||
Stock,
|
||||
|
||||
Reference in New Issue
Block a user