config list-builder: Allow overriding the per-item build method

This will be useful especially for simple lists where the entry
doesn't need a separate builder type.
This commit is contained in:
Ian Jackson 2022-04-25 13:36:13 +01:00
parent d98d7a60bd
commit 961f6b527e
4 changed files with 17 additions and 2 deletions

1
Cargo.lock generated
View File

@ -3342,6 +3342,7 @@ dependencies = [
"serde",
"shellexpand-fork",
"thiserror",
"tor-basic-utils",
"tor-error",
"tracing",
"tracing-test",

View File

@ -15,6 +15,7 @@ default = ["expand-paths"]
expand-paths = ["shellexpand", "directories"]
[dependencies]
tor-basic-utils = { path="../tor-basic-utils", version = "0.2.0"}
tor-error = { path="../tor-error", version = "0.2.0"}
thiserror = "1"

View File

@ -55,6 +55,8 @@ pub use err::{ConfigBuildError, ReconfigureError};
pub use mut_cfg::MutCfg;
pub use path::CfgPath;
pub use tor_basic_utils::macro_coalesce_args;
/// Rules for reconfiguring a running Arti instance.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]

View File

@ -17,6 +17,10 @@
/// nontrivial, you should put the actual defaulting functionality in a (probably-private)
/// function, as the macro will expand it twice.
///
/// The `item_build` clause, if supplied, provides a closure with type
/// `FnMut(&ThingBuilder) -> Result<Thing, ConfigBuildErro>`; the default is to call
/// `thing_builder.build()`.
///
/// ```
/// use derive_builder::Builder;
/// use serde::Deserialize;
@ -59,6 +63,7 @@ macro_rules! define_list_config_builder {
}
built: $Built:ty = $built:expr;
default = $default:expr;
$( item_build: $item_build:expr; )?
} => {
$($docs_and_attrs)*
#[derive(Default, Clone, Deserialize)]
@ -100,10 +105,16 @@ macro_rules! define_list_config_builder {
&default_buffer
}
};
let $things = $things
.iter()
.map(|item| item.build())
.collect::<Result<_, _>>()?;
.map(
$crate::macro_coalesce_args!{
[ $( $item_build )? ],
[ |item| item.build() ],
}
)
.collect::<Result<_, ConfigBuildError>>()?;
Ok($built)
}
}