Derive Macro smart_config::DescribeConfig 
source · #[derive(DescribeConfig)]
{
    // Attributes available to this derive:
    #[config]
}
Expand description
Derives the DescribeConfig trait for a type.
This macro supports both structs and enums. It is conceptually similar to Deserialize macro from serde.
Macro behavior can be configured with #[config(_)] attributes. Multiple #[config(_)] attributes
on a single item are supported.
Each field in the struct / each enum variant is considered a configuration param (by default),
or a sub-config (if #[config(nest)] or #[config(flatten)] is present for the field).
§Container attributes
§validate
Type: One of the following:
- Expression evaluating to a Validateimplementation (e.g., aRange; see theValidatedocs for implementations). An optional human-readable string validation description may be provided delimited by the comma (e.g., to make the description more domain-specific).
- Pointer to a function with the fn(&_) -> Result<(), ErrorWithOrigin>signature and the validation description separated by a comma.
- Pointer to a function with the fn(&_) -> boolsignature and the validation description separated by a comma. Validation fails if the function returnsfalse.
See the examples in the validation module.
Specifies a post-deserialization validation for the config. This is useful to check invariants involving multiple params. Multiple validations are supported by specifying the attribute multiple times.
§tag
Type: string
Specifies the param name holding the enum tag, similar to the corresponding attribute in serde.
Unlike serde, this attribute is required for enums; this is to ensure that source merging is well-defined.
§rename_all
Type: string; one of lowercase, UPPERCASE, camelCase, snake_case, SCREAMING_SNAKE_CASE,
kebab-case, SCREAMING-KEBAB-CASE
Renames all variants in an enum config according to the provided transform. Unlike in serde, this attribute
only works on enum variants. Params / sub-configs are always expected to have snake_case naming.
Caveats:
- rename_allassumes that original variant names are in- PascalCase(i.e., follow Rust naming conventions).
- rename_allrequires original variant names to consist of ASCII chars.
- Each letter of capitalized acronyms (e.g., “HTTP” in HTTPServer) is treated as a separate word. E.g.,rename_all = "snake_case"will renameHTTPServertoh_t_t_p_server. Note that it is recommended to not capitalize acronyms (i.e., useHttpServer).
- No spacing is inserted before numbers or other non-letter chars. E.g., rename_all = "snake_case"will renameStatus500tostatus500, not tostatus_500.
§derive(Default)
Derives Default according to the default values of params (+ the default variant for enum configs).
To work, all params must have a default value specified.
§Variant attributes
§rename, alias
Type: string
Have the same meaning as in serde; i.e. allow to rename / specify additional names for the tag(s)
corresponding to the variant. alias can be specified multiple times.
§default
If specified, marks the variant as default – one which will be used if the tag param is not set in the input. At most one variant can be marked as default.
§Field attributes
§rename, alias
Type: string
Have the same meaning as in serde; i.e. allow to rename / specify additional names for the param or a nested config.
Names are validated in compile time.
In addition to simple names, path aliases are supported as well. A path alias starts with . and consists of dot-separated segments,
e.g. .experimental.value or ..value. The paths are resolved relative to the config prefix. As in Python, more than one dot
at the start of the path signals that the path is relative to the parent(s) of the config.
- alias = ".experimental.value"with config prefix- testresolves to the absolute path- test.experimental.value.
- alias = "..value"with config prefix- test.experimentalresolves to the absolute path- test.value.
If an alias requires more parents than is present in the config prefix, the alias is not applicable.
(E.g., alias = "...value" with config prefix test.)
Path aliases are somewhat difficult to reason about, so avoid using them unless necessary.
§deprecated
Type: string
Similar to alias, with the difference that the alias is marked as deprecated in the schema docs,
and its usages are logged on the WARN level.
§default
Type: path to function (optional)
Has the same meaning as in serde, i.e. allows to specify a constructor of the default value for the param.
Without a value, Default is used for this purpose. Unlike serde, the path shouldn’t be quoted.
§default_t
Type: expression with param type
Allows to specify the default typed value for the param. The provided expression doesn’t need to be constant.
§example
Type: expression with field type
Allows to specify the example value for the param. The example value can be specified together with the default / default_t
attribute. In this case, the example value can be more “complex” than the default, to better illustrate how the configuration works.
§fallback
Type: constant expression evaluating to &'static dyn FallbackSource
Allows to provide a fallback source for the param. See the fallback module docs for the discussion of fallbacks
and intended use cases.
§with
Type: const expression implementing DeserializeParam
Allows changing the param deserializer. See de module docs for the overview of available deserializers.
For Options, with refers to the internal type deserializer; it will be wrapped into an Optional automatically.
Note that there is an alternative: implementing WellKnown for the param type.
§nest
If specified, the field is treated as a nested sub-config rather than a param. Correspondingly, its type must
implement DescribeConfig, or wrap such a type in an Option.
§flatten
If specified, the field is treated as a flattened sub-config rather than a param. Unlike nest, its params
will be added to the containing config instead of a separate object. The sub-config type must implement DescribeConfig.
§validate
Has same semantics as config validations, but applies to a specific config parameter.
§deserialize_if
Type: same as config validations
Filters an Optional value. This is useful to coerce semantically invalid values (e.g., empty strings for URLs)
to None in the case automated null coercion doesn’t apply.
See the validation module for examples of usage.
§Validations
The following validations are performed by the macro in compile time:
- Param / sub-config names and aliases must be non-empty, consist of lowercase ASCII alphanumeric chars or underscore
and not start with a digit (i.e., follow the [a-z_][a-z0-9_]*regex).
- Param names / aliases cannot coincide with nested config names.
§Examples
use smart_config::metadata::TimeUnit;
#[derive(DescribeConfig, DeserializeConfig)]
struct TestConfig {
    /// Doc comments are parsed as a description.
    #[config(default_t = 3)]
    int: u32,
    #[config(default)] // multiple `config` attrs are supported
    #[config(rename = "str", alias = "string")]
    renamed: String,
    /// Nested sub-config. E.g., the tag will be read from path `nested.version`.
    #[config(nest)]
    nested: NestedConfig,
    /// Flattened sub-config. E.g., `array` param will be read from `array`, not `flat.array`.
    #[config(flatten)]
    flat: FlattenedConfig,
}
#[derive(DescribeConfig, DeserializeConfig)]
#[config(tag = "version", rename_all = "snake_case", derive(Default))]
enum NestedConfig {
    #[config(default)]
    V0,
    #[config(alias = "latest")]
    V1 {
        /// Param with a custom deserializer. In this case, it will deserialize
        /// a duration from a number with milliseconds unit of measurement.
        #[config(default_t = Duration::from_millis(50), with = TimeUnit::Millis)]
        latency_ms: Duration,
        /// `Vec`s, sets and other containers are supported out of the box.
        set: HashSet<NonZeroUsize>,
    },
}
#[derive(DescribeConfig, DeserializeConfig)]
struct FlattenedConfig {
    #[config(default = FlattenedConfig::default_array)]
    array: [f32; 2],
}
impl FlattenedConfig {
    const fn default_array() -> [f32; 2] { [1.0, 2.0] }
}