Skip to main content

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;
37pub mod validate;
38mod value;
39mod value_ref;
40
41use key::PartialKeyCollector;
42
43/// Automatic derive [`FromConfig`] instance.
44///
45/// We use annotation attributes to customize the derived instances' behavior.
46/// All attributes in `cfg-rs` have format `#[config(key = value, key2 = value2)]`.
47///
48/// # Struct Annotation Attribute
49///
50/// * `#[config(prefix = "cfg.app")]`
51///
52/// This attr will lead to implement trait [`FromConfigWithPrefix`].
53///
54/// ```ignore,rust
55/// #[derive(FromConfig)]
56/// #[config(prefix = "cfg.test")]
57/// struct Test {
58///   //fields...   
59/// }
60/// ```
61///
62/// # Crate Annotation Attribute
63///
64/// * `#[config(crate = "cfg")]`
65///
66/// This attr will specify the crate name of `cfg-rs` in generated code. It is useful when you rename the crate in `Cargo.toml`.
67///
68/// ```ignore,rust
69/// // In Cargo.toml
70/// // [dependencies]
71/// // cfg = { path = "../cfg-rs" }
72///
73/// #[derive(FromConfig)]
74/// #[config(crate = "cfg")]
75/// struct Test {
76///   //fields...   
77/// }
78/// ```
79///
80/// # Field Annotation Attribute
81///
82/// * `#[config(name = "val")]`
83///
84/// This attr will replace the default config partial key, which is name of field.
85///
86/// ```ignore,rust
87/// #[derive(FromConfig)]
88/// struct Test {
89///   val: u8,
90///   #[config(name = "val")]
91///   other: u8, // This field `other` will use the same partial key as `val`.
92/// }
93/// ```
94///
95/// * `#[config(default = true)]`
96///
97/// This attr provides default value for underlying field.
98///
99/// ```ignore,rust
100/// #[derive(FromConfig)]
101/// struct Test {
102///   enabled: bool, // User must provide value for this field.
103///   #[config(default = true)]
104///   enabled_with_default: bool, // This field has default value `true`.
105/// }
106/// ```
107pub use cfg_derive::FromConfig;
108pub use configuration::{ConfigContext, Configuration, PredefinedConfigurationBuilder};
109pub use derive::FromConfigWithPrefix;
110pub use err::ConfigError;
111pub(crate) use err::ConfigLock;
112pub use key::ConfigKey;
113pub use prelude::*;
114#[allow(unused_imports)]
115#[cfg(feature = "log")]
116pub use value::log as _;
117#[allow(unused_imports)]
118#[cfg(feature = "coarsetime")]
119pub use value::time as _;
120pub use value::{ConfigValue, FromStrHolder, FromStringValue, FromValue};
121pub use value_ref::RefValue;
122
123#[doc(hidden)]
124pub use source::cargo::Cargo;
125#[doc(hidden)]
126pub use source::file::inline_source_config;
127
128use std::sync::*;
129
130pub(crate) mod macros {
131    macro_rules! cfg_log {
132    ($b:expr => $lvl:expr,$($arg:tt)+) => {
133        #[cfg(feature = "log")]
134        {
135            if  $b {
136                log::log!($lvl, $($arg)+);
137            }
138        }
139    };
140    ($lvl:expr,$($arg:tt)+) => {
141        #[cfg(feature = "log")]
142        {
143            log::log!($lvl, $($arg)+);
144        }
145    };
146    }
147
148    macro_rules! impl_default {
149        ($x:ident) => {
150            impl ::core::default::Default for $x {
151                fn default() -> Self {
152                    Self::new()
153                }
154            }
155        };
156    }
157
158    pub(crate) use cfg_log;
159    pub(crate) use impl_default;
160}
161
162/// Generate config instance from configuration.
163///
164/// The most power of this crate is automatically deriving this trait.
165/// Please refer to [Derive FromConfig](./derive.FromConfig.html) for details.
166pub trait FromConfig: Sized {
167    /// Generate config from [`ConfigValue`] under context.
168    fn from_config(
169        context: &mut ConfigContext<'_>,
170        value: Option<ConfigValue<'_>>,
171    ) -> Result<Self, ConfigError>;
172}