How to transfer program state, like a window position, to the next run?

Viewed 46

What would be the proper way to store tiny bit of data to reuse?

I am thinking about creating options.json file. Any instruments for it? Another options?

1 Answers

I was a bit bored, so here is the solution you were looking for. It attempts to save an options.json file in the same directory as the executable.

use serde::{Serialize, Deserialize};
use serde::de::DeserializeOwned;
use std::env::current_exe;
use std::io::{self, BufReader, BufWriter, Error, ErrorKind};
use std::fs::File;

pub fn save_data_for_next<D: Serialize>(data: &D) -> io::Result<()> {
    let options_path = current_exe()?.parent().unwrap().join("options.json");
    let writer = BufWriter::new(File::create(options_path)?);
    serde_json::to_writer(writer, data).map_err(|e| Error::new(ErrorKind::Other, e))
}


pub fn load_previous_data<D: DeserializeOwned>() -> io::Result<Option<D>> {
    let options_path = current_exe()?.parent().unwrap().join("options.json");
    
    if !options_path.is_file() {
        return Ok(None)
    } 
    
    let reader = BufReader::new(File::open(options_path)?);
    match serde_json::from_reader(reader) {
        Ok(v) => Ok(Some(v)),
        Err(e) => Err(Error::new(ErrorKind::Other, e))
    }
}

Then all you need to do to use it is to derive Serialize and Deserialize on some type. Alternatively you could use serde_json::Value, then it would be able to safely save/load any arbitrary JSON values. However, you may need to manually delete the options.json file when you change the contents of Options since it may panic upon failing to parse the previous version.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Options {
    window_position: (u32, u32),
}

pub fn main() {
    let mut options = match load_previous_data::<Options>().unwrap() {
        Some(v) => v,
        // Options has not been created yet, so create some default config
        None => Options {
            window_size: (500, 500),
        },
    };

    // Run program

    // Save options before exiting
    save_data_for_next(&options).unwrap();
}
Related