WIP: Initial commit for savefile migration #133

Draft
not_a_segfault wants to merge 12 commits from not_a_segfault/PowerTools:dev into dev
3 changed files with 35 additions and 3 deletions
Showing only changes of commit 627708e0d9 - Show all commits

View file

@ -23,7 +23,7 @@ pub enum ApiMessage {
OnChargeChange(f64), // battery fill amount: 0 = empty, 1 = full OnChargeChange(f64), // battery fill amount: 0 = empty, 1 = full
PowerVibeCheck, PowerVibeCheck,
WaitForEmptyQueue(Callback<()>), WaitForEmptyQueue(Callback<()>),
LoadSettings(u64, String, u64, String), // (path, name, variant, variant name) LoadSettings(Option<(u64, String)>, u64, String, u64, String), // ((legacy game_id, legacy name), path, name, variant, variant name)
LoadVariant(u64, String), // (variant, variant name) -- path and name assumed to be for current profile LoadVariant(u64, String), // (variant, variant name) -- path and name assumed to be for current profile
LoadMainSettings, LoadMainSettings,
LoadSystemSettings, LoadSystemSettings,
@ -504,7 +504,7 @@ impl ApiMessageHandler {
self.on_empty.push(callback); self.on_empty.push(callback);
false false
} }
ApiMessage::LoadSettings(id, name, variant_id, variant_name) => { ApiMessage::LoadSettings(legacy_settings, id, name, variant_id, variant_name) => {
/* Migration steps: /* Migration steps:
1. Modify to the frontend to send the game ID in this message (`id` here is the app 1. Modify to the frontend to send the game ID in this message (`id` here is the app
ID). ID).
@ -514,6 +514,21 @@ impl ApiMessageHandler {
save in the new format yet. save in the new format yet.
4. Let the rest of the code below work its magic. 4. Let the rest of the code below work its magic.
*/ */
// If `legacy_settings` is `Some`, there is a legacy savefile present.
if let Some((legacy_game_id, legacy_name)) = legacy_settings {
// Create path to the legacy settings file.
let legacy_file_path = format!("{}.json", legacy_game_id);
// Load the file from disk and deserialize it.
let file = crate::persist::OldSettingsJson::open(legacy_file_path);
// If a file in the modern format exists, add it as a new variant to
// `FileJson` using `FileJson::merge_legacy_settings()`. Else, create a new
// FileJson with this as the only variant, using
// `FileJson::from<OldSettingsJson>()`.
}
let path = format!("{}.ron", id); let path = format!("{}.ron", id);
if let Err(e) = settings.on_unload() { if let Err(e) = settings.on_unload() {
print_errors("LoadSettings on_unload()", e); print_errors("LoadSettings on_unload()", e);

View file

@ -36,6 +36,14 @@ impl From<ron::error::Error> for RonError {
} }
} }
impl From<serde_json::Error> for RonError {
fn from(_value: serde_json::Error) -> Self {
RonError::General(ron::Error::Message(String::from(
"TODO: make error handling in migration logic good. Specifically, make it so a json error can be used as a RonError instead of just returning this string",
)))
}
}
impl From<ron::error::SpannedError> for RonError { impl From<ron::error::SpannedError> for RonError {
fn from(value: ron::error::SpannedError) -> Self { fn from(value: ron::error::SpannedError) -> Self {
Self::Spanned(value) Self::Spanned(value)

View file

@ -2,7 +2,9 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::persist::{BatteryJson, CpuJson, DriverJson, FileJson, SettingsJson, LATEST_VERSION}; use crate::persist::{
BatteryJson, CpuJson, DriverJson, FileJson, SerdeError, SettingsJson, LATEST_VERSION,
};
use super::gpu::OldGpuJson; use super::gpu::OldGpuJson;
@ -56,3 +58,10 @@ impl From<OldSettingsJson> for FileJson {
} }
} }
} }
impl OldSettingsJson {
pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, SerdeError> {
let mut file = std::fs::File::open(path).map_err(SerdeError::Io)?;
serde_json::from_reader(&mut file).map_err(|e| SerdeError::Serde(e.into()))
}
}