Module smart_config::de

source ·
Expand description

Configuration deserialization logic.

§How it works

DeserializeConfig derive macro visits all config parameters invoking associated DeserializeParam implementations. Unlike serde deserialization, deserialization does not stop early on error (we want to get errors for all params). Nested / flattened configs do not use serde either for a couple of reasons:

  • To reach all params regardless of encountered errors as mentioned above
  • serde sometimes collects params in intermediate containers (e.g., in structs with #[serde(flatten)] or in tagged enums), which leads to param deserialization potentially getting broken in unpredictable ways.

So, each config param is deserialized in isolation from an optional Value WithOrigin encapsulated in DeserializeContext.

§Deserializers

The default deserializer is extracted from the param type with the help of WellKnown and WellKnownOption traits. If you have a custom type defined locally which you want to use in configs, the easiest solution would be to implement WellKnown (+ maybe WellKnownOption) for it. Alternatively, it’s possible to specify a custom deserializer using #[config(with = _)] attribute.

§Universal deserializers

Serde (usually instantiated via the eponymous macro) can deserialize any param implementing serde::Deserialize. An important caveat is that these deserializers require the input Value to be present; otherwise, they’ll fail with a “missing value” error. As such, for Optional types, it’s necessary to wrap a deserializer in the Optional decorator.

§Durations and byte sizes

Durations and ByteSizes can be deserialized in two ways:

  • By default, they are deserialized from an integer + unit either encapsulated in a string like “200ms” or in a single-key object like { "mb": 4 }. See WithUnit for more details.
  • Alternatively, TimeUnit and SizeUnit can be used on Durations and ByteSizes, respectively.

§Secrets

A param is secret iff it uses a Secret deserializer (perhaps, with decorators on top, like Optional / WithDefault). Secret params must be deserializable from a string; this is because strings are the only type of secret values currently supported.

Secret values are wrapped in opaque, zero-on-drop wrappers during source preprocessing so that they do not get accidentally exposed via debug logs etc. See ConfigRepository for details.

Macros§

Structs§

  • Deserializer that supports either an array of values, or a string in which values are delimited by the specified separator.
  • Context for deserializing a configuration.
  • Available deserialization options.
  • Deserializer from JSON objects.
  • Deserializer for secret strings (any type convertible from SecretString, including SecretString itself). Will set the corresponding flag for ParamMetadata, making raw param value hidden in the debug output etc.
  • Deserializer that supports either a map or an array of { key: _, value: _ } tuples (with customizable key / value names). Created using Entries::named().
  • Deserializer decorator that wraps the output of the underlying decorator in Some and returns None if the input for the param is missing.
  • Deserializer that supports parsing either from a default format (usually an object or array) via Deserialize, or from string via FromStr.
  • Deserializer decorator that provides additional details for the deserialized type.
  • Deserializer from JSON arrays.
  • Deserializer for arbitrary secret params. Will set the corresponding flag for ParamMetadata, making raw param value hidden in the debug output etc.
  • Deserializer powered by serde. Usually created with the help of Serde! macro; see its docs for the examples of usage.
  • Deserializer decorator that defaults to the provided value if the input for the param is missing.
  • Default deserializer for Durations and ByteSizes.

Traits§