pub mod migrate;
pub mod versions;
use crate::game::state::GameState;
pub const CURRENT_VERSION: u32 = 2;
pub fn load_from_str(json: &str) -> GameState {
match migrate::peek_version(json) {
1 => match serde_json::from_str::<versions::v1::GameStateV1>(json) {
Ok(v1) => versions::v2::GameStateV2::from(v1)
.into_current()
.migrate_runtime(),
Err(_) => GameState::default().migrate_runtime(),
},
2 => match serde_json::from_str::<versions::v2::GameStateV2>(json) {
Ok(v2) => v2.into_current().migrate_runtime(),
Err(_) => GameState::default().migrate_runtime(),
},
_ => GameState::default().migrate_runtime(),
}
}
pub fn save_to_string(state: &GameState) -> serde_json::Result<String> {
serde_json::to_string_pretty(state)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pre_versioned_json_loads_through_v1() {
let legacy = r#"{
"cuques": 1234.5,
"total_clicks": 99,
"lifetime_cuques": 1234.5,
"best_fps": 0.0,
"golden_caught": 0,
"fingerers_owned": {"index_finger": 7},
"achievements_earned": ["first_finger"],
"upgrades_earned": ["click_mult_1"],
"prestige": 0,
"total_play_ticks": 0,
"buffs": []
}"#;
let s = load_from_str(legacy);
assert_eq!(s.version, CURRENT_VERSION);
assert_eq!(s.cuques, 1234.5);
assert_eq!(s.total_clicks, 99);
assert_eq!(s.fingerer_count("index_finger"), 7);
assert!(s.has_upgrade("click_mult_1"));
assert!(s.has_achievement("first_finger"));
}
#[test]
fn malformed_json_falls_back_to_default() {
let s = load_from_str("{ not valid json");
assert_eq!(s.cuques, 0.0);
assert_eq!(s.version, CURRENT_VERSION);
}
#[test]
fn round_trip_through_save_to_string_preserves_state() {
let original = GameState {
cuques: 4242.0,
total_clicks: 17,
..GameState::default()
};
let json = save_to_string(&original).expect("serialize");
let loaded = load_from_str(&json);
assert_eq!(loaded.cuques, 4242.0);
assert_eq!(loaded.total_clicks, 17);
assert_eq!(loaded.version, CURRENT_VERSION);
}
}