cr_program_settings/
settings_container.rs

1//! `SettingsContainer` source file
2#![warn(missing_docs)]
3
4use crate::{
5    load_settings_with_filename, save_settings_with_filename, LoadSettingsError, SaveSettingsError,
6};
7use serde::{Deserialize, Serialize};
8
9/// Struct that handles saving and loading.
10#[derive(Serialize, Deserialize, PartialEq, Debug, Eq)]
11pub struct SettingsContainer<T> {
12    /// Generic settings inner field.
13    settings: Option<T>,
14    /// The name of the parent folder of where the file will be saved to.
15    crate_name: String,
16    /// The filename to save this struct
17    file_name: String,
18}
19
20impl<T> SettingsContainer<T>
21where
22    for<'a> T: Serialize + Deserialize<'a>,
23{
24    /// Creates a new `SettingsContainer`
25    pub fn new(content: T, crate_name: &str, file_name: &str) -> Self {
26        Self {
27            settings: Some(content),
28            crate_name: crate_name.to_string(),
29            file_name: file_name.to_string(),
30        }
31    }
32
33    /// Gets the settings optional within the struct
34    pub fn get_settings(&self) -> &Option<T> {
35        &self.settings
36    }
37
38    /// Gets the mutable settings optional
39    pub fn get_mut_settings(&mut self) -> Option<&mut T> {
40        self.settings.as_mut()
41    }
42
43    /// Sets the settings optional within the struct
44    pub fn set_settings(&mut self, settings: T) {
45        self.settings = Some(settings);
46    }
47
48    /// Attempts to load a settings container, if it fails, it will return a default `SettingsContainer`
49    /// ```
50    /// use serde::{Deserialize, Serialize};
51    /// use cr_program_settings::settings_container::SettingsContainer;
52    ///
53    /// #[derive(Serialize,Deserialize,PartialEq,Debug)]
54    /// struct InnerStruct {
55    /// field1: u32,
56    /// field2: bool,
57    /// field3: String,
58    /// }
59    ///
60    /// let inner = InnerStruct{
61    /// field1: 124,field2: true,field3: "cool struct data in a string!".to_string(),};
62    ///
63    /// let settings = SettingsContainer::new(inner,env!("CARGO_CRATE_NAME"),"doctest_save_settings.ser");
64    ///
65    /// let _ = settings.save().expect("Failed to save settings container to file");
66    ///
67    /// // This should load settings successfully
68    /// let loaded_settings_success = SettingsContainer::<InnerStruct>::try_load_or_default(env!("CARGO_CRATE_NAME"),"doctest_save_settings.ser");
69    /// assert_eq!(loaded_settings_success, settings);
70    ///
71    /// // This should fail, and resort to the default settings
72    /// let loaded_settings_failed = SettingsContainer::<InnerStruct>::try_load_or_default(env!("CARGO_CRATE_NAME"),"not_a_settings_file.ser");
73    /// assert_eq!(loaded_settings_failed, SettingsContainer::default(env!("CARGO_CRATE_NAME"),"not_a_settings_file.ser"));
74    /// ```
75    pub fn try_load_or_default(crate_name: &str, file_name: &str) -> Self {
76        match SettingsContainer::<T>::load(crate_name, file_name) {
77            Ok(settings_container) => settings_container,
78            Err(_) => Self::default(crate_name, file_name),
79        }
80    }
81
82    /// Returns a default `SettingsContainer`
83    pub fn default(crate_name: &str, file_name: &str) -> Self {
84        Self {
85            settings: None,
86            crate_name: crate_name.to_string(),
87            file_name: file_name.to_string(),
88        }
89    }
90
91    /// Loads a settings container using a `crate_name` and `file_name`, returns a `Ok(SettingsContainer)` or `Err(LoadSettingsError)`
92    /// For a `unwrap_or_default` style, use try_load_or_default()
93    /// For example usage, see save() or try_load_or_default() documentation
94    pub fn load(crate_name: &str, file_name: &str) -> Result<Self, LoadSettingsError> {
95        load_settings_with_filename(crate_name, file_name)
96    }
97
98    /// Saves a settings container using its `crate_name` and `file_name` within the struct.
99    /// ```
100    /// use cr_program_settings::settings_container::SettingsContainer;
101    ///
102    /// let settings = SettingsContainer::new("some_cool_data".to_string(),env!("CARGO_CRATE_NAME"),"doctest_save_settings.ser");
103    ///
104    /// let _ = settings.save().expect("Failed to save settings container to file");
105    ///
106    /// let loaded_settings = SettingsContainer::load(env!("CARGO_CRATE_NAME"),"doctest_save_settings.ser").unwrap();
107    ///
108    /// assert_eq!(settings,loaded_settings);
109    /// ```
110    pub fn save(&self) -> Result<(), SaveSettingsError> {
111        save_settings_with_filename(&self.crate_name, &self.file_name, self)
112    }
113}