zng/
config.rs

1#![cfg(feature = "config")]
2
3//! Config service, sources and other types.
4//!
5//! The configuration service [`CONFIG`] separates config using from config writing. A config
6//! is a variable of a serializable type, widgets and other components request a config using an unique text name and
7//! then simply use the variable like any other. The app optionally sets one or more config sources that are automatically
8//! updated when a config variable changes and are monitored for changes that are propagated back to the config variables.
9//!
10//! # Sources
11//!
12//! The default config source is the [`MemoryConfig`] that only lives for the app process lifetime, this can
13//! be used to connect different UI components, more importantly it also means that the [`CONFIG`] service always works
14//! so widgets can just set configs in case a persisting source is setup.
15//!
16//! ```
17//! use zng::prelude::*;
18//!
19//! fn txt_input() -> impl UiNode {
20//!     TextInput!(CONFIG.get("example.txt", Txt::from("")))
21//! }
22//!
23//! fn txt_display() -> impl UiNode {
24//!     Text!(CONFIG.get("example.txt", Txt::from("")))
25//! }
26//!
27//! # fn main() { }
28//! # fn demo() {
29//! # let _scope = APP.defaults();
30//! # let _ =
31//! Container! {
32//!     child = txt_input();
33//!     child_bottom = txt_display(), 20;
34//! }
35//! # ; }
36//! ```
37//!
38//! The example above uses a config `"example.txt"`, the text will be wiped when the app is closed, but the app
39//! components are ready in case they are used in an app that enables persistent config.
40//!
41//! The example below setups a [`JsonConfig`] that persists the configs to a JSON file. The file updates when
42//! a config variable is modified and the variables are updated when the file is modified externally.
43//!
44//! ```
45//! # use zng::prelude::*;
46//! # fn main() { }
47//! # fn demo() {
48//! # let _scope = APP.defaults();
49//! let cfg = zng::config::JsonConfig::sync("target/tmp/example.config.json");
50//! CONFIG.load(cfg);
51//! # }
52//! ```
53//!
54//! ## Other Sources
55//!
56//! The JSON format is available by default, TOML, YAML and RON are also available behind a feature flags, you can
57//! also implement your own source.
58//!
59//! Apart from config sources that represents a format some *meta* sources are provided, they enables composite sources,
60//! such as having two sources app default and user where the user config file only records the non-default values.
61//!
62//! The crate example `examples/config.rs` demonstrates a more complex setup:
63//!
64//! ```
65//! use zng::config::*;
66//!
67//! fn load_config() -> Box<dyn FallbackConfigReset> {
68//!     // config file for the app, keys with prefix "main." are saved here.
69//!     let user_cfg = JsonConfig::sync("target/tmp/example.config.json");
70//!     // entries not found in `user_cfg` bind to this file first before going to embedded fallback.
71//!     let default_cfg = ReadOnlyConfig::new(JsonConfig::sync("examples/res/config/defaults.json"));
72//!
73//!     // the app settings.
74//!     let main_cfg = FallbackConfig::new(user_cfg, default_cfg);
75//!
76//!     // Clone a ref that can be used to reset specific entries.
77//!     let main_ref = main_cfg.clone_boxed();
78//!
79//!     // any other configs (Window::save_state for example)
80//!     let other_cfg = JsonConfig::sync("target/tmp/example.config.other.json");
81//!
82//!     CONFIG.load(SwitchConfig::new().with_prefix("main.", main_cfg).with_prefix("", other_cfg));
83//!
84//!     main_ref
85//! }
86//! ```
87//!
88//! # Full API
89//!
90//! See [`zng_ext_config`] for the full config API.
91
92pub use zng_ext_config::{
93    AnyConfig, CONFIG, Config, ConfigKey, ConfigStatus, ConfigValue, FallbackConfig, FallbackConfigReset, JsonConfig, MemoryConfig,
94    RawConfigValue, ReadOnlyConfig, SwapConfig, SwitchConfig,
95};
96
97#[cfg(feature = "window")]
98pub use zng_wgt_window::{SaveState, save_state_node};
99
100#[cfg(feature = "ron")]
101pub use zng_ext_config::RonConfig;
102
103#[cfg(feature = "toml")]
104pub use zng_ext_config::TomlConfig;
105
106#[cfg(feature = "yaml")]
107pub use zng_ext_config::YamlConfig;
108
109/// Settings are the config the user can directly edit, this module implements a basic settings data model.
110///
111/// # Full API
112///
113/// See [`zng_ext_config::settings`] for the full settings API.
114pub mod settings {
115    pub use zng_ext_config::settings::{
116        CategoriesBuilder, Category, CategoryBuilder, CategoryId, SETTINGS, Setting, SettingBuilder, SettingsBuilder,
117    };
118    pub use zng_wgt_input::cmd::{SETTINGS_CMD, on_pre_settings, on_settings};
119
120    /// Settings editor widget.
121    ///
122    /// # Full API
123    ///
124    /// See [`zng_wgt_settings`] for the full settings editor API.
125    #[cfg(feature = "settings_editor")]
126    pub mod editor {
127        pub use zng_wgt_settings::{
128            CategoriesListArgs, CategoryHeaderArgs, CategoryItemArgs, SettingArgs, SettingBuilderEditorExt, SettingsArgs, SettingsCtxExt,
129            SettingsEditor, categories_list_fn, category_header_fn, category_item_fn, setting_fn, settings_fn,
130        };
131    }
132}