macro_rules! impl_standard_builder {
    {
        $Config:ty $(: $($options:tt)* )?
    } => { ... };
    {
        @ ( $($Builder        :ident)? )
          ( $($default        :ident)? )
          ( $($try_deserialize:ident)? ) $Config:ty : $(+)? !Deserialize $( $options:tt )*
    } => { ... };
    {
        @ ( $($Builder        :ident)? )
          ( $($default        :ident)? )
          ( $($try_deserialize:ident)? ) $Config:ty : $(+)? !Builder     $( $options:tt )*
    } => { ... };
    {
        @ ( $($Builder        :ident)? )
          ( $($default        :ident)? )
          ( $($try_deserialize:ident)? ) $Config:ty : $(+)? !Default     $( $options:tt )*
    } => { ... };
    {
        @ ( $($Builder        :ident)? )
          ( $($default        :ident)? )
          ( $($try_deserialize:ident)? ) $Config:ty : $(+)?
    } => { ... };
}
Expand description

Defines standard impls for a struct with a Builder, incl Default

Use this. Do not #[derive(Builder, Default)]. That latter approach would produce wrong answers if builder attributes are used to specify non-Default default values.

§Input syntax

use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use tor_config::impl_standard_builder;
use tor_config::ConfigBuildError;

#[derive(Debug, Builder, Clone, Eq, PartialEq)]
#[builder(derive(Serialize, Deserialize, Debug))]
#[builder(build_fn(error = "ConfigBuildError"))]
struct SomeConfigStruct { }
impl_standard_builder! { SomeConfigStruct }

#[derive(Debug, Builder, Clone, Eq, PartialEq)]
struct UnusualStruct { }
impl_standard_builder! { UnusualStruct: !Deserialize + !Builder }

§Requirements

$Config’s builder must have default values for all the fields, or this macro-generated self-test will fail. This should be OK for all principal elements of our configuration.

$ConfigBuilder must have an appropriate Deserialize impl.

§Options

  • !Default suppresses the Default implementation, and the corresponding tests. This should be done within Arti’s configuration only for sub-structures which contain mandatory fields (and are themselves optional).

  • !Deserialize suppresses the test case involving Builder: Deserialize. This should not be done for structs which are part of Arti’s configuration, but can be appropriate for other types that use [derive_builder].

  • !Builder suppresses the impl of the tor_config::load::Builder trait This will be necessary if the error from the builder is not ConfigBuildError.

§Generates

  • impl Default for $Config
  • impl Builder for $ConfigBuilder
  • a self-test that the Default impl actually works
  • a test that the Builder can be deserialized from an empty [config::Config], and then built, and that the result is the same as the ordinary default.