Reputation: 7372
I have a config that I want initialized on startup, but not have to re-read the file every time. To do this, I'm using lazy_static:
lazy_static! {
static ref SETTINGS: Settings = {
match Settings::init() {
Ok(c) => c,
Err(e) => panic!("{}", e),
}
};
}
But now I have a method that updates that config file, and I want to "re-initialize" / update it, without having to re-start the program.
pub fn save_config_file(data: &str) -> Result<String, Error> {
fs::write(CONFIG_FILE, data)?;
SETTINGS = {
match Settings::init() {
Ok(c) => c, // The line with the error
Err(e) => panic!("{}", e),
}
};
Self::read_config_file()
}
Which gives me the error: [rustc E0308] [E] mismatched types expected struct settings::SETTINGS, found struct settings::Settings
Is there any way to re-initialize a lazy_static? Or do I have to restart the program?
Upvotes: 3
Views: 2993
Reputation: 7372
Okay, figured this one out. Mainly from here: How do I assign a String to a mutable static variable?
Add derive Clone to your struct:
#[derive(Debug, Deserialize, Clone)]
Wrap your lazy_static in an RwLock
, initialize it normally.
use std::sync::RwLock;
lazy_static! {
static ref SETTINGS: RwLock<Settings> = RwLock::new(
match Settings::init() {
Ok(c) => c,
Err(e) => panic!("{}", e),
}
);
}
To read, you can do this:
pub fn get() -> Self {
SETTINGS.read().unwrap().to_owned()
}
To write:
let mut new_settings = SETTINGS.write().unwrap();
*new_settings = match Settings::init() {
Ok(c) => c,
Err(e) => panic!("{}", e),
};
Upvotes: 4