I have code:
static mut SETTINGS: Option<Settings> = None;
pub struct Settings {
pub(crate) db_path: String,
pub(crate) is_debug: bool
}
pub fn create_settings(settings: Settings) {
unsafe {
SETTINGS = Option::from(settings)
}
}
pub mod get {
pub fn db_path() -> String {
unsafe {super::SETTINGS.expect("Settings not definition").db_path}
}
}
And I get errors
error[E0507]: cannot move out of static item `SETTINGS`
--> src/settings.rs:16:17
|
16 | unsafe {super::SETTINGS.expect("Settings not definition").db_path}
| ^^^^^^^^^^^^^^^ move occurs because `SETTINGS` has type `std::option::Option<Settings>`, which does not implement the `Copy` trait
I need a static structure and get fields from it. How do I write getter functions so I can just call functions and get settings instead of passing a reference to a struct. Settings are global and alone
>Solution :
You could use once_cell::OnceCell for that (notice that it can be set just once):
use once_cell::sync::OnceCell;
static SETTINGS: OnceCell<Settings> = OnceCell::new();
#[derive(Debug)]
pub struct Settings {
pub(crate) db_path: String,
pub(crate) is_debug: bool
}
pub fn create_settings(settings: Settings) {
SETTINGS.set(settings).expect("Set should occur only once")
}
pub mod get {
pub fn db_path<'a>() -> &'a str {
&super::SETTINGS.get().expect("Settings not definition").db_path
}
}
Also notice that the return type of db_path changed, it is now &'a str, you can return a reference to the string. If you really want it to return a String then you would have to Clone it.
Most probably you would need also just plain OnceCell, your methods would be just wrapper around it (access and setting).