Simplify config API types and accessors, and config handling code
For each FooConfig
:
- Make
FooConfigBuilder
Serialize and Deserialize; - Make the validated configuration no longer Serialize and Deserialize
-
Make;FooConfig
the builder type -
Have the validated configuration be a hidden type that is created when passing theSadly this is not going to be possible, since the validated type must be convyed through the various API layers so that the builders can work.FooConfig
to a constructor. MakeFooConfig::validate
pub
, while havingFooConfig::build
be private.
Improve cases where BigConfig
contains a LittleConfig
.
- Automatically generate the code to convert and validate
LittleConfig
toLittleConfigValidated
and put it intoBigConfigValidated.little
. (This is necessary for the above changes becauseBigConfigValidated.little
must beLittleConfigValidated
, but the builder must contain aLittleConfig
not aLittleConfigValidated
.) - Instead of providing a setter method on
BigConfig
that expects to consume aLittleConfig
, provide an accessor methodimpl BigConfig { pub fn little(&mut self) -> &mut LittleConfig; }
. [1]
This should considerably reduce the amount of code in our tree, although it requires new feature(s) in derive_builder
.
[1] Rationale: this allows the caller to set a sub-field big.little.wombat
by writing bit.little().wombat(Wombat)
rather than making an entirely new LittleConfig
. The latter is clumsy and also risks accidental overwrites if different parts of the calling code want to modify different fields of big.little
. (If we move fields out of little
, API could be preserved by making LittleConfig
a newtype with appropriate handwritten accessors which redirect the field accessors.)
This is part of #285 (closed).
Edited by Ian Jackson