Is there an elegant way to save a variable/s so that a state is reflected between executions. I think reading and updating a config file (yaml) is a pretty good solution but for just a couple of variables it seems a bit of a hastle. Any thoughts?
>Solution :
I think you misuse term runtimes, I think what you mean is executions. But I think I get what you are trying to ask. This is not Rust-specific. Executables in general are stateless, they do not store any information between executions.
So if you want to persist state between executions, you need to store it somewhere. The options are many. The most common ones are files or databases.
If it’s really just a couple of variables the easiest way would probably be json via the awesome serde_json library. With it, you can convert normal Rust structs into human readable ASCII text and store it in file.
You could even wrap it in a struct that can load/store the state.
Although you have to be careful with concurrent access then.
Here is a somewhat simple example of a struct that can persists its state in a file:
use serde::{Deserialize, Serialize};
use std::{fs::File, io::BufReader, path::Path};
const STATE_FILENAME: &'static str = "state.json";
#[derive(Serialize, Deserialize)]
struct PersistentState {
counter: u32,
}
impl PersistentState {
fn load() -> Self {
let path = Path::new(STATE_FILENAME);
if path.exists() && path.is_file() {
let file = File::open(path).unwrap();
serde_json::from_reader(BufReader::new(file)).unwrap()
} else {
Self::default()
}
}
fn store(&self) {
let file = File::create(STATE_FILENAME).unwrap();
serde_json::to_writer(file, self).unwrap();
}
}
impl Default for PersistentState {
fn default() -> Self {
Self { counter: 0 }
}
}
fn main() {
let mut state = PersistentState::load();
state.counter += 1;
println!("Counter: {}", state.counter);
state.store();
}
First execution:
Counter: 1
Second execution:
Counter: 2
state.json file:
{"counter":2}
Of course don’t just copy-paste the code into your project but instead think about your usecase and adapt it to your needs.
Pitfalls
Not all types are losslessly storable in json. Most are, like strings, integers and booleans, but floats are not. Floats are stored in human readable decimal, but stored in binary, and there is always a small rounding error in the conversion. But unless you are doing scientific calculations, that is most likely irrelevant.
If you don’t like json, serde supports a bunch of other types as well.