cfg_rs/lib.rs
1#![doc = include_str!("../README.md")]
2#![doc(issue_tracker_base_url = "https://github.com/leptonyu/cfg-rs/issues/")]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
5#![allow(unused_attributes)]
6#![warn(
7 anonymous_parameters,
8 missing_copy_implementations,
9 missing_debug_implementations,
10 missing_docs,
11 nonstandard_style,
12 rust_2018_idioms,
13 single_use_lifetimes,
14 trivial_casts,
15 trivial_numeric_casts,
16 unreachable_pub,
17 unused_extern_crates,
18 unused_qualifications,
19 variant_size_differences
20)]
21
22#[cfg_attr(coverage_nightly, coverage(off))]
23#[cfg(test)]
24mod test;
25#[cfg(test)]
26#[macro_use(quickcheck)]
27extern crate quickcheck_macros;
28
29mod cache;
30mod configuration;
31mod derive;
32mod err;
33mod key;
34
35mod prelude;
36pub mod source;
37mod value;
38mod value_ref;
39
40use key::PartialKeyCollector;
41
42/// Automatic derive [`FromConfig`] instance.
43///
44/// We use annotation attributes to customize the derived instances' behavior.
45/// All attributes in `cfg-rs` have format `#[config(key = value, key2 = value2)]`.
46///
47/// # Struct Annotation Attribute
48///
49/// * `#[config(prefix = "cfg.app")]`
50///
51/// This attr will lead to implement trait [`FromConfigWithPrefix`].
52///
53/// ```ignore,rust
54/// #[derive(FromConfig)]
55/// #[config(prefix = "cfg.test")]
56/// struct Test {
57/// //fields...
58/// }
59/// ```
60///
61/// # Crate Annotation Attribute
62///
63/// * `#[config(crate = "cfg")]`
64///
65/// This attr will specify the crate name of `cfg-rs` in generated code. It is useful when you rename the crate in `Cargo.toml`.
66///
67/// ```ignore,rust
68/// // In Cargo.toml
69/// // [dependencies]
70/// // cfg = { path = "../cfg-rs" }
71///
72/// #[derive(FromConfig)]
73/// #[config(crate = "cfg")]
74/// struct Test {
75/// //fields...
76/// }
77/// ```
78///
79/// # Field Annotation Attribute
80///
81/// * `#[config(name = "val")]`
82///
83/// This attr will replace the default config partial key, which is name of field.
84///
85/// ```ignore,rust
86/// #[derive(FromConfig)]
87/// struct Test {
88/// val: u8,
89/// #[config(name = "val")]
90/// other: u8, // This field `other` will use the same partial key as `val`.
91/// }
92/// ```
93///
94/// * `#[config(default = true)]`
95///
96/// This attr provides default value for underlying field.
97///
98/// ```ignore,rust
99/// #[derive(FromConfig)]
100/// struct Test {
101/// enabled: bool, // User must provide value for this field.
102/// #[config(default = true)]
103/// enabled_with_default: bool, // This field has default value `true`.
104/// }
105/// ```
106pub use cfg_derive::FromConfig;
107pub use configuration::{ConfigContext, Configuration, PredefinedConfigurationBuilder};
108pub use derive::FromConfigWithPrefix;
109pub use err::ConfigError;
110pub(crate) use err::ConfigLock;
111pub use key::ConfigKey;
112pub use prelude::*;
113#[allow(unused_imports)]
114#[cfg(feature = "log")]
115pub use value::log as _;
116#[allow(unused_imports)]
117#[cfg(feature = "coarsetime")]
118pub use value::time as _;
119pub use value::{ConfigValue, FromStrHolder, FromStringValue, FromValue};
120pub use value_ref::RefValue;
121
122#[doc(hidden)]
123pub use source::cargo::Cargo;
124#[doc(hidden)]
125pub use source::file::inline_source_config;
126
127use std::sync::*;
128
129pub(crate) mod macros {
130 macro_rules! cfg_log {
131 ($b:expr => $lvl:expr,$($arg:tt)+) => {
132 #[cfg(feature = "log")]
133 {
134 if $b {
135 log::log!($lvl, $($arg)+);
136 }
137 }
138 };
139 ($lvl:expr,$($arg:tt)+) => {
140 #[cfg(feature = "log")]
141 {
142 log::log!($lvl, $($arg)+);
143 }
144 };
145 }
146
147 macro_rules! impl_default {
148 ($x:ident) => {
149 impl ::core::default::Default for $x {
150 fn default() -> Self {
151 Self::new()
152 }
153 }
154 };
155 }
156
157 pub(crate) use cfg_log;
158 pub(crate) use impl_default;
159}
160
161/// Generate config instance from configuration.
162///
163/// The most power of this crate is automatically deriving this trait.
164/// Please refer to [Derive FromConfig](./derive.FromConfig.html) for details.
165pub trait FromConfig: Sized {
166 /// Generate config from [`ConfigValue`] under context.
167 fn from_config(
168 context: &mut ConfigContext<'_>,
169 value: Option<ConfigValue<'_>>,
170 ) -> Result<Self, ConfigError>;
171}