pub struct ConfigManager<T> { /* private fields */ }Expand description
Manages one typed JSON settings file.
ConfigManager<T> stores and loads a complete configuration value of type
T. The type must implement Serde Serialize and DeserializeOwned.
The manager is intentionally small. It owns only:
- the directory containing the settings file,
- the settings file name,
- the JSON output format, and
- the save strategy.
Implementations§
Source§impl<T> ConfigManager<T>where
T: Serialize + DeserializeOwned,
impl<T> ConfigManager<T>where
T: Serialize + DeserializeOwned,
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a config manager using the OS-standard config directory and the current executable name.
On Windows desktop apps this resolves under %APPDATA%. Pure UWP apps
should use with_root_dir or the optional
uwp feature instead.
This constructor cannot report failure without an API break, so it falls back silently in two places instead of erroring:
- if the platform configuration directory cannot be determined (for
example, no
HOMEor%APPDATA%in the environment), it falls back to the current directory (.); - if the current executable’s name cannot be determined, or is not a
safe path component, it falls back to the literal name
"app".
The second fallback is a fixed constant. Any two executables that
both hit it resolve to the same settings file and can silently read
and overwrite each other’s settings. If that is not acceptable, use
try_new to fail instead of falling back, or
for_app to supply an explicit identity so nothing
is derived in the first place.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 let root = std::env::temp_dir().join("app-json-settings-update-example");
21 let manager = ConfigManager::<AppSettings>::new()
22 .with_root_dir(root)
23 .try_with_filename("settings.json")?;
24
25 let updated = manager.update(|settings| {
26 settings.launch_count += 1;
27 if settings.theme.is_empty() {
28 settings.theme = "system".to_string();
29 }
30 })?;
31
32 println!("settings path: {}", manager.path().display());
33 println!("launch count: {}", updated.launch_count);
34 println!("theme: {}", updated.theme);
35
36 Ok(())
37}More examples
23fn main() -> app_json_settings::Result<()> {
24 // The production desktop form is usually:
25 //
26 // let manager = ConfigManager::<AppSettings>::for_app("my-gui-app")?;
27 //
28 // This example uses a temporary root so running it does not write to your
29 // real app settings directory.
30 let root = std::env::temp_dir().join("app-json-settings-basic-example");
31 let manager = ConfigManager::<AppSettings>::new()
32 .with_root_dir(root)
33 .try_with_filename("settings.json")?;
34
35 let settings = manager.load_or_default()?;
36
37 println!("settings path: {}", manager.path().display());
38 println!("theme: {}", settings.theme);
39 println!(
40 "window: {}x{}",
41 settings.window_width, settings.window_height
42 );
43
44 Ok(())
45}19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}10fn main() -> app_json_settings::Result<()> {
11 let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12 let manager = ConfigManager::<AppSettings>::new()
13 .with_root_dir(&root)
14 .try_with_filename("settings.json")?;
15
16 // Simulate a settings file left unreadable by an external edit, so this
17 // example actually exercises the recovery branch below instead of
18 // silently taking the happy path. A real application would not do this;
19 // it would simply encounter an already-invalid file.
20 std::fs::create_dir_all(&root)?;
21 std::fs::write(manager.path(), "not-json")?;
22
23 let settings = match manager.load_or_default() {
24 Ok(settings) => settings,
25 Err(ConfigError::Deserialize(error)) => {
26 eprintln!("settings file is invalid, moving it aside: {error}");
27
28 // The backup carries the same sensitivity as the original
29 // settings file. Handle it with the same care you would give
30 // the original (see docs/src/save-behavior.md for the Unix
31 // permission model this crate applies to the file itself).
32 let backup = manager.path().with_extension("json.bak");
33 std::fs::rename(manager.path(), &backup)?;
34 println!("backed up invalid settings to: {}", backup.display());
35
36 manager.load_or_default()?
37 }
38 Err(error) => return Err(error),
39 };
40
41 println!("settings path: {}", manager.path().display());
42 println!("theme: {}", settings.theme);
43 println!("launch count: {}", settings.launch_count);
44
45 Ok(())
46}Sourcepub fn try_new() -> Result<Self>
pub fn try_new() -> Result<Self>
Creates a config manager using the OS-standard config directory and the current executable name, failing rather than silently substituting either.
Fail-closed counterpart to new: returns
ConfigError::Platform if the platform configuration directory
cannot be resolved, or if the current executable’s name cannot be
determined or is not a safe path component – the two cases new()
papers over with . and "app" respectively. Both failures report
through the same variant with distinguishable messages, since adding
a dedicated variant would itself be a breaking change: ConfigError
is not #[non_exhaustive], so a new variant breaks any exhaustive
match on it.
Prefer this over new() when you genuinely want the executable’s
derived name but sharing a settings file with another executable
that hits the same fallback is not acceptable. If you have a stable
application identity to supply instead, prefer
for_app, which needs no derivation at all.
Sourcepub fn for_app(app_name: &str) -> Result<Self>
pub fn for_app(app_name: &str) -> Result<Self>
Creates a config manager for an explicit application name.
This is the recommended desktop constructor for production apps because
the storage directory is stable even if the executable file name changes.
The app_name must be a single safe path component, not a path.
Returns ConfigError::Platform if the platform configuration
directory cannot be resolved (for example, no HOME or %APPDATA% in
the environment). Applications that hit this in practice — typically
services or containers without a user environment — should supply a
path explicitly with with_root_dir instead.
Sourcepub fn at_current_dir(self) -> Self
pub fn at_current_dir(self) -> Self
Stores the settings file in the current working directory.
If the current working directory cannot be determined, falls back to
".". Unlike for_app, this fallback is not
surprising here: the caller explicitly asked for working-directory
storage, and "." already means “the working directory” to the
filesystem.
Sourcepub fn with_root_dir<P: Into<PathBuf>>(self, path: P) -> Self
pub fn with_root_dir<P: Into<PathBuf>>(self, path: P) -> Self
Stores the settings file in a caller-provided directory.
This is the primary compatibility seam for sandboxed hosts, including Pure UWP. The host application may resolve its application data directory and pass it here.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 let root = std::env::temp_dir().join("app-json-settings-update-example");
21 let manager = ConfigManager::<AppSettings>::new()
22 .with_root_dir(root)
23 .try_with_filename("settings.json")?;
24
25 let updated = manager.update(|settings| {
26 settings.launch_count += 1;
27 if settings.theme.is_empty() {
28 settings.theme = "system".to_string();
29 }
30 })?;
31
32 println!("settings path: {}", manager.path().display());
33 println!("launch count: {}", updated.launch_count);
34 println!("theme: {}", updated.theme);
35
36 Ok(())
37}More examples
23fn main() -> app_json_settings::Result<()> {
24 // The production desktop form is usually:
25 //
26 // let manager = ConfigManager::<AppSettings>::for_app("my-gui-app")?;
27 //
28 // This example uses a temporary root so running it does not write to your
29 // real app settings directory.
30 let root = std::env::temp_dir().join("app-json-settings-basic-example");
31 let manager = ConfigManager::<AppSettings>::new()
32 .with_root_dir(root)
33 .try_with_filename("settings.json")?;
34
35 let settings = manager.load_or_default()?;
36
37 println!("settings path: {}", manager.path().display());
38 println!("theme: {}", settings.theme);
39 println!(
40 "window: {}x{}",
41 settings.window_width, settings.window_height
42 );
43
44 Ok(())
45}19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}10fn main() -> app_json_settings::Result<()> {
11 let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12 let manager = ConfigManager::<AppSettings>::new()
13 .with_root_dir(&root)
14 .try_with_filename("settings.json")?;
15
16 // Simulate a settings file left unreadable by an external edit, so this
17 // example actually exercises the recovery branch below instead of
18 // silently taking the happy path. A real application would not do this;
19 // it would simply encounter an already-invalid file.
20 std::fs::create_dir_all(&root)?;
21 std::fs::write(manager.path(), "not-json")?;
22
23 let settings = match manager.load_or_default() {
24 Ok(settings) => settings,
25 Err(ConfigError::Deserialize(error)) => {
26 eprintln!("settings file is invalid, moving it aside: {error}");
27
28 // The backup carries the same sensitivity as the original
29 // settings file. Handle it with the same care you would give
30 // the original (see docs/src/save-behavior.md for the Unix
31 // permission model this crate applies to the file itself).
32 let backup = manager.path().with_extension("json.bak");
33 std::fs::rename(manager.path(), &backup)?;
34 println!("backed up invalid settings to: {}", backup.display());
35
36 manager.load_or_default()?
37 }
38 Err(error) => return Err(error),
39 };
40
41 println!("settings path: {}", manager.path().display());
42 println!("theme: {}", settings.theme);
43 println!("launch count: {}", settings.launch_count);
44
45 Ok(())
46}Sourcepub fn at_custom_dir<P: Into<PathBuf>>(self, path: P) -> Self
pub fn at_custom_dir<P: Into<PathBuf>>(self, path: P) -> Self
Stores the settings file in a caller-provided directory.
This method is kept for compatibility with v2.0.x. Prefer
with_root_dir in new code.
Sourcepub fn with_filename(self, name: &str) -> Self
pub fn with_filename(self, name: &str) -> Self
Changes the settings file name without validation.
This method is retained for v2.x compatibility. New code should prefer
try_with_filename, which rejects path-like
names such as ../settings.json.
Sourcepub fn try_with_filename(self, name: &str) -> Result<Self>
pub fn try_with_filename(self, name: &str) -> Result<Self>
Changes the settings file name after validating it as a plain file name.
The accepted value must be a single file name, not an absolute path and not a relative path containing directory traversal.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 let root = std::env::temp_dir().join("app-json-settings-update-example");
21 let manager = ConfigManager::<AppSettings>::new()
22 .with_root_dir(root)
23 .try_with_filename("settings.json")?;
24
25 let updated = manager.update(|settings| {
26 settings.launch_count += 1;
27 if settings.theme.is_empty() {
28 settings.theme = "system".to_string();
29 }
30 })?;
31
32 println!("settings path: {}", manager.path().display());
33 println!("launch count: {}", updated.launch_count);
34 println!("theme: {}", updated.theme);
35
36 Ok(())
37}More examples
23fn main() -> app_json_settings::Result<()> {
24 // The production desktop form is usually:
25 //
26 // let manager = ConfigManager::<AppSettings>::for_app("my-gui-app")?;
27 //
28 // This example uses a temporary root so running it does not write to your
29 // real app settings directory.
30 let root = std::env::temp_dir().join("app-json-settings-basic-example");
31 let manager = ConfigManager::<AppSettings>::new()
32 .with_root_dir(root)
33 .try_with_filename("settings.json")?;
34
35 let settings = manager.load_or_default()?;
36
37 println!("settings path: {}", manager.path().display());
38 println!("theme: {}", settings.theme);
39 println!(
40 "window: {}x{}",
41 settings.window_width, settings.window_height
42 );
43
44 Ok(())
45}19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}10fn main() -> app_json_settings::Result<()> {
11 let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12 let manager = ConfigManager::<AppSettings>::new()
13 .with_root_dir(&root)
14 .try_with_filename("settings.json")?;
15
16 // Simulate a settings file left unreadable by an external edit, so this
17 // example actually exercises the recovery branch below instead of
18 // silently taking the happy path. A real application would not do this;
19 // it would simply encounter an already-invalid file.
20 std::fs::create_dir_all(&root)?;
21 std::fs::write(manager.path(), "not-json")?;
22
23 let settings = match manager.load_or_default() {
24 Ok(settings) => settings,
25 Err(ConfigError::Deserialize(error)) => {
26 eprintln!("settings file is invalid, moving it aside: {error}");
27
28 // The backup carries the same sensitivity as the original
29 // settings file. Handle it with the same care you would give
30 // the original (see docs/src/save-behavior.md for the Unix
31 // permission model this crate applies to the file itself).
32 let backup = manager.path().with_extension("json.bak");
33 std::fs::rename(manager.path(), &backup)?;
34 println!("backed up invalid settings to: {}", backup.display());
35
36 manager.load_or_default()?
37 }
38 Err(error) => return Err(error),
39 };
40
41 println!("settings path: {}", manager.path().display());
42 println!("theme: {}", settings.theme);
43 println!("launch count: {}", settings.launch_count);
44
45 Ok(())
46}Sourcepub fn disable_pretty_json(self) -> Self
pub fn disable_pretty_json(self) -> Self
Stores JSON in compact form instead of pretty-printed form.
Sourcepub fn with_save_mode(self, mode: SaveMode) -> Self
pub fn with_save_mode(self, mode: SaveMode) -> Self
Selects the save strategy.
The default is SaveMode::Atomic. Use SaveMode::Direct only when
an application intentionally wants v2.2-style direct overwrite behavior
or needs to work around unusual filesystem semantics.
Sourcepub fn with_direct_save(self) -> Self
pub fn with_direct_save(self) -> Self
Selects direct overwrite saves.
This is a convenience alias for with_save_mode(SaveMode::Direct).
Sourcepub fn folder_path(&self) -> &Path
pub fn folder_path(&self) -> &Path
Returns the settings folder path.
Sourcepub fn path(&self) -> PathBuf
pub fn path(&self) -> PathBuf
Returns the settings file path.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 let root = std::env::temp_dir().join("app-json-settings-update-example");
21 let manager = ConfigManager::<AppSettings>::new()
22 .with_root_dir(root)
23 .try_with_filename("settings.json")?;
24
25 let updated = manager.update(|settings| {
26 settings.launch_count += 1;
27 if settings.theme.is_empty() {
28 settings.theme = "system".to_string();
29 }
30 })?;
31
32 println!("settings path: {}", manager.path().display());
33 println!("launch count: {}", updated.launch_count);
34 println!("theme: {}", updated.theme);
35
36 Ok(())
37}More examples
23fn main() -> app_json_settings::Result<()> {
24 // The production desktop form is usually:
25 //
26 // let manager = ConfigManager::<AppSettings>::for_app("my-gui-app")?;
27 //
28 // This example uses a temporary root so running it does not write to your
29 // real app settings directory.
30 let root = std::env::temp_dir().join("app-json-settings-basic-example");
31 let manager = ConfigManager::<AppSettings>::new()
32 .with_root_dir(root)
33 .try_with_filename("settings.json")?;
34
35 let settings = manager.load_or_default()?;
36
37 println!("settings path: {}", manager.path().display());
38 println!("theme: {}", settings.theme);
39 println!(
40 "window: {}x{}",
41 settings.window_width, settings.window_height
42 );
43
44 Ok(())
45}19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}10fn main() -> app_json_settings::Result<()> {
11 let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12 let manager = ConfigManager::<AppSettings>::new()
13 .with_root_dir(&root)
14 .try_with_filename("settings.json")?;
15
16 // Simulate a settings file left unreadable by an external edit, so this
17 // example actually exercises the recovery branch below instead of
18 // silently taking the happy path. A real application would not do this;
19 // it would simply encounter an already-invalid file.
20 std::fs::create_dir_all(&root)?;
21 std::fs::write(manager.path(), "not-json")?;
22
23 let settings = match manager.load_or_default() {
24 Ok(settings) => settings,
25 Err(ConfigError::Deserialize(error)) => {
26 eprintln!("settings file is invalid, moving it aside: {error}");
27
28 // The backup carries the same sensitivity as the original
29 // settings file. Handle it with the same care you would give
30 // the original (see docs/src/save-behavior.md for the Unix
31 // permission model this crate applies to the file itself).
32 let backup = manager.path().with_extension("json.bak");
33 std::fs::rename(manager.path(), &backup)?;
34 println!("backed up invalid settings to: {}", backup.display());
35
36 manager.load_or_default()?
37 }
38 Err(error) => return Err(error),
39 };
40
41 println!("settings path: {}", manager.path().display());
42 println!("theme: {}", settings.theme);
43 println!("launch count: {}", settings.launch_count);
44
45 Ok(())
46}Sourcepub fn save(&self, config: &T) -> Result<()>
pub fn save(&self, config: &T) -> Result<()>
Saves the complete configuration, replacing the existing file content.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}Source§impl<T> ConfigManager<T>
impl<T> ConfigManager<T>
Sourcepub fn load_or_default(&self) -> Result<T>
pub fn load_or_default(&self) -> Result<T>
Loads the configuration, or creates and saves T::default() on first run.
Examples found in repository?
23fn main() -> app_json_settings::Result<()> {
24 // The production desktop form is usually:
25 //
26 // let manager = ConfigManager::<AppSettings>::for_app("my-gui-app")?;
27 //
28 // This example uses a temporary root so running it does not write to your
29 // real app settings directory.
30 let root = std::env::temp_dir().join("app-json-settings-basic-example");
31 let manager = ConfigManager::<AppSettings>::new()
32 .with_root_dir(root)
33 .try_with_filename("settings.json")?;
34
35 let settings = manager.load_or_default()?;
36
37 println!("settings path: {}", manager.path().display());
38 println!("theme: {}", settings.theme);
39 println!(
40 "window: {}x{}",
41 settings.window_width, settings.window_height
42 );
43
44 Ok(())
45}More examples
19fn main() -> app_json_settings::Result<()> {
20 // Caller-provided roots are useful for portable apps, tests, sandboxed
21 // hosts, and UWP-style apps where the host resolves its own local folder.
22 let root = std::env::temp_dir().join("app-json-settings-custom-root-example");
23
24 let manager = ConfigManager::<PortableSettings>::new()
25 .with_root_dir(&root)
26 .try_with_filename("preferences.json")?;
27
28 let mut settings = manager.load_or_default()?;
29
30 if settings.recent_files.is_empty() {
31 settings
32 .recent_files
33 .push("/example/documents/readme.md".to_string());
34 manager.save(&settings)?;
35 }
36
37 println!("custom root: {}", root.display());
38 println!("settings file: {}", manager.path().display());
39 println!("recent files: {:?}", settings.recent_files);
40
41 Ok(())
42}10fn main() -> app_json_settings::Result<()> {
11 let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12 let manager = ConfigManager::<AppSettings>::new()
13 .with_root_dir(&root)
14 .try_with_filename("settings.json")?;
15
16 // Simulate a settings file left unreadable by an external edit, so this
17 // example actually exercises the recovery branch below instead of
18 // silently taking the happy path. A real application would not do this;
19 // it would simply encounter an already-invalid file.
20 std::fs::create_dir_all(&root)?;
21 std::fs::write(manager.path(), "not-json")?;
22
23 let settings = match manager.load_or_default() {
24 Ok(settings) => settings,
25 Err(ConfigError::Deserialize(error)) => {
26 eprintln!("settings file is invalid, moving it aside: {error}");
27
28 // The backup carries the same sensitivity as the original
29 // settings file. Handle it with the same care you would give
30 // the original (see docs/src/save-behavior.md for the Unix
31 // permission model this crate applies to the file itself).
32 let backup = manager.path().with_extension("json.bak");
33 std::fs::rename(manager.path(), &backup)?;
34 println!("backed up invalid settings to: {}", backup.display());
35
36 manager.load_or_default()?
37 }
38 Err(error) => return Err(error),
39 };
40
41 println!("settings path: {}", manager.path().display());
42 println!("theme: {}", settings.theme);
43 println!("launch count: {}", settings.launch_count);
44
45 Ok(())
46}Sourcepub fn update<F>(&self, f: F) -> Result<T>
pub fn update<F>(&self, f: F) -> Result<T>
Applies a read-modify-write update and saves the result.
Examples found in repository?
19fn main() -> app_json_settings::Result<()> {
20 let root = std::env::temp_dir().join("app-json-settings-update-example");
21 let manager = ConfigManager::<AppSettings>::new()
22 .with_root_dir(root)
23 .try_with_filename("settings.json")?;
24
25 let updated = manager.update(|settings| {
26 settings.launch_count += 1;
27 if settings.theme.is_empty() {
28 settings.theme = "system".to_string();
29 }
30 })?;
31
32 println!("settings path: {}", manager.path().display());
33 println!("launch count: {}", updated.launch_count);
34 println!("theme: {}", updated.theme);
35
36 Ok(())
37}Trait Implementations§
Source§impl<T: Clone> Clone for ConfigManager<T>
impl<T: Clone> Clone for ConfigManager<T>
Source§fn clone(&self) -> ConfigManager<T>
fn clone(&self) -> ConfigManager<T>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more