smart_config/_docs/derive_ref.rs
1//! # Derive macros reference
2//!
3//! All 3 proc macros exported by the library ([`DescribeConfig`](macro@crate::DescribeConfig),
4//! [`DeserializeConfig`](macro@crate::DeserializeConfig) and [`ExampleConfig`](macro@crate::ExampleConfig))
5//! share the same attributes detailed below.
6//!
7//! These macros support both structs and enums. Macro specifications are conceptually similar
8//! to the `Deserialize` macro from `serde`.
9//! Macro behavior can be configured with `#[config(_)]` attributes. Multiple `#[config(_)]` attributes
10//! on a single item are supported.
11//!
12//! Each field in the struct / each enum variant is considered a configuration param (by default),
13//! or a sub-config (if `#[config(nest)]` or `#[config(flatten)]` is present for the field).
14//!
15//! # Container attributes
16//!
17//! ## `validate`
18//!
19//! **Type:** One of the following:
20//!
21//! - Expression evaluating to a [`Validate`](crate::validation::Validate) implementation (e.g., a [`Range`](std::ops::Range); see the `Validate` docs
22//! for implementations). An optional human-readable string validation description may be provided delimited by the comma (e.g., to make the description
23//! more domain-specific).
24//! - Pointer to a function with the `fn(&_) -> Result<(), ErrorWithOrigin>` signature and the validation description separated by a comma.
25//! - Pointer to a function with the `fn(&_) -> bool` signature and the validation description separated by a comma. Validation fails
26//! if the function returns `false`.
27//!
28//! See the examples in the [`validation`](crate::validation) module.
29//!
30//! Specifies a post-deserialization validation for the config. This is useful to check invariants involving multiple params.
31//! Multiple validations are supported by specifying the attribute multiple times.
32//!
33//! ## `tag`
34//!
35//! **Type:** string
36//!
37//! Specifies the param name holding the enum tag, similar to the corresponding attribute in `serde`.
38//! Unlike `serde`, this attribute is *required* for enums; this is to ensure that source merging is well-defined.
39//!
40//! ## `rename_all`
41//!
42//! **Type:** string; one of `lowercase`, `UPPERCASE`, `camelCase`, `snake_case`, `SCREAMING_SNAKE_CASE`,
43//! `kebab-case`, `SCREAMING-KEBAB-CASE`
44//!
45//! Renames all variants in an enum config according to the provided transform. Unlike in `serde`, this attribute
46//! *only* works on enum variants. Params / sub-configs are always expected to have `snake_case` naming.
47//!
48//! Caveats:
49//!
50//! - `rename_all` assumes that original variant names are in `PascalCase` (i.e., follow Rust naming conventions).
51//! - `rename_all` requires original variant names to consist of ASCII chars.
52//! - Each letter of capitalized acronyms (e.g., "HTTP" in `HTTPServer`) is treated as a separate word.
53//! E.g., `rename_all = "snake_case"` will rename `HTTPServer` to `h_t_t_p_server`.
54//! Note that [it is recommended][clippy-acronyms] to not capitalize acronyms (i.e., use `HttpServer`).
55//! - No spacing is inserted before numbers or other non-letter chars. E.g., `rename_all = "snake_case"`
56//! will rename `Status500` to `status500`, not to `status_500`.
57//!
58//! [clippy-acronyms]: https://rust-lang.github.io/rust-clippy/master/index.html#/upper_case_acronyms
59//!
60//! ## `derive(Default)`
61//!
62//! Derives `Default` according to the default values of params (+ the default variant for enum configs).
63//! To work, all params must have a default value specified.
64//!
65//! # Variant attributes
66//!
67//! ## `rename`, `alias`
68//!
69//! **Type:** string
70//!
71//! Have the same meaning as in `serde`; i.e. allow to rename / specify additional names for the tag(s)
72//! corresponding to the variant. `alias` can be specified multiple times.
73//!
74//! ## `default`
75//!
76//! If specified, marks the variant as default – one which will be used if the tag param is not set in the input.
77//! At most one variant can be marked as default.
78//!
79//! # Field attributes
80//!
81//! ## `rename`, `alias`
82//!
83//! **Type:** string
84//!
85//! Have the same meaning as in `serde`; i.e. allow to rename / specify additional names for the param or a nested config.
86//! Names are [validated](#validations) in compile time.
87//!
88//! In addition to simple names, *path* aliases are supported as well. A path alias starts with `.` and consists of dot-separated segments,
89//! e.g. `.experimental.value` or `..value`. The paths are resolved relative to the config prefix. As in Python, more than one dot
90//! at the start of the path signals that the path is relative to the parent(s) of the config.
91//!
92//! - `alias = ".experimental.value"` with config prefix `test` resolves to the absolute path `test.experimental.value`.
93//! - `alias = "..value"` with config prefix `test.experimental` resolves to the absolute path `test.value`.
94//!
95//! If an alias requires more parents than is present in the config prefix, the alias is not applicable.
96//! (E.g., `alias = "...value"` with config prefix `test`.)
97//!
98//! Path aliases are somewhat difficult to reason about, so avoid using them unless necessary.
99//!
100//! ## `deprecated`
101//!
102//! **Type:** string
103//!
104//! Similar to `alias`, with the difference that the alias is marked as deprecated in the schema docs,
105//! and its usages are logged on the `WARN` level.
106//!
107//! ## `default`
108//!
109//! **Type:** path to function (optional)
110//!
111//! Has the same meaning as in `serde`, i.e. allows to specify a constructor of the default value for the param.
112//! Without a value, [`Default`] is used for this purpose. Unlike `serde`, the path shouldn't be quoted.
113//!
114//! ## `default_t`
115//!
116//! **Type:** expression with param type
117//!
118//! Allows to specify the default typed value for the param. The provided expression doesn't need to be constant.
119//!
120//! ## `example`
121//!
122//! **Type:** expression with field type
123//!
124//! Allows to specify the example value for the param. The example value can be specified together with the `default` / `default_t`
125//! attribute. In this case, the example value can be more "complex" than the default, to better illustrate how the configuration works.
126//!
127//! ## `fallback`
128//!
129//! **Type:** constant expression evaluating to `&'static dyn `[`FallbackSource`](crate::fallback::FallbackSource)
130//!
131//! Allows to provide a fallback source for the param. See the [`fallback`](crate::fallback) module docs for the discussion of fallbacks
132//! and intended use cases.
133//!
134//! ## `with`
135//!
136//! **Type:** const expression implementing [`DeserializeParam`]
137//!
138//! Allows changing the param deserializer. See [`de`](crate::de) module docs for the overview of available deserializers.
139//! For `Option`s, `with` refers to the *internal* type deserializer; it will be wrapped into an [`Optional`](crate::de::Optional) automatically.
140//!
141//! Note that there is an alternative: implementing [`WellKnown`](crate::de::WellKnown) for the param type.
142//!
143//! ## `nest`
144//!
145//! If specified, the field is treated as a nested sub-config rather than a param. Correspondingly, its type must
146//! implement `DescribeConfig`, or wrap such a type in an `Option`.
147//!
148//! ## `flatten`
149//!
150//! If specified, the field is treated as a *flattened* sub-config rather than a param. Unlike `nest`, its params
151//! will be added to the containing config instead of a separate object. The sub-config type must implement `DescribeConfig`.
152//!
153//! ## `validate`
154//!
155//! Has same semantics as [config validations](#validate), but applies to a specific config parameter.
156//!
157//! ## `deserialize_if`
158//!
159//! **Type:** same as [config validations](#validate)
160//!
161//! Filters an `Option`al value. This is useful to coerce semantically invalid values (e.g., empty strings for URLs)
162//! to `None` in the case [automated null coercion](crate::de::Optional#encoding-nulls) doesn't apply.
163//! See the [`validation`](crate::validation) module for examples of usage.
164//!
165//! # Validations
166//!
167//! The following validations are performed by the macro in compile time:
168//!
169//! - Param / sub-config names and aliases must be non-empty, consist of lowercase ASCII alphanumeric chars or underscore
170//! and not start with a digit (i.e., follow the `[a-z_][a-z0-9_]*` regex).
171//! - Param names / aliases cannot coincide with nested config names.
172//!
173//! [`DeserializeParam`]: crate::de::DeserializeParam