Module tor_config::list_builder
source · Expand description
Lists in builders
Use define_list_builder_helper
and define_list_builder_accessors
together when
a configuration (or other struct with a builder)
wants to contain a Vec
of config sub-entries.
How to use these macros
-
For each kind of list, define a
ThingList
type alias for the validated form, and calldefine_list_builder_helper
to define aThingListBuilder
helper type. (Different lists with the same Rust type, but which ought to have a different default, are different “kinds” and should each have a separately named type alias.)(Or, alternatively, with a hand-written builder type, make the builder field be
Option<Vec<ElementBuilder>>
.) -
For each struct field containing a list, in a struct deriving
Builder
, decorate the field with#[builder(sub_builder, setter(custom))]
to (i) getderive_builder
call the appropriate build method, (ii) suppress thederive_builder
-generated setter. -
For each struct containing lists, call
define_list_builder_accessors
to define the accessor methods.
Example - list of structs with builders
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use tor_config::{define_list_builder_helper, define_list_builder_accessors, ConfigBuildError};
#[derive(Builder, Debug, Eq, PartialEq)]
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Debug, Serialize, Deserialize))]
pub struct Thing { value: i32 }
#[derive(Builder, Debug, Eq, PartialEq)]
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Debug, Serialize, Deserialize))]
pub struct Outer {
/// List of things, being built as part of the configuration
#[builder(sub_builder, setter(custom))]
things: ThingList,
}
define_list_builder_accessors! {
struct OuterBuilder {
pub things: [ThingBuilder],
}
}
/// Type alias for use by list builder macrology
type ThingList = Vec<Thing>;
define_list_builder_helper! {
pub(crate) struct ThingListBuilder {
pub(crate) things: [ThingBuilder],
}
built: ThingList = things;
default = vec![];
}
let mut builder = OuterBuilder::default();
builder.things().push(ThingBuilder::default().value(42).clone());
assert_eq!{ builder.build().unwrap().things, &[Thing { value: 42 }] }
builder.set_things(vec![ThingBuilder::default().value(38).clone()]);
assert_eq!{ builder.build().unwrap().things, &[Thing { value: 38 }] }
Example - list of trivial values
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use tor_config::{define_list_builder_helper, define_list_builder_accessors, ConfigBuildError};
#[derive(Builder, Debug, Eq, PartialEq)]
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Debug, Serialize, Deserialize))]
pub struct Outer {
/// List of values, being built as part of the configuration
#[builder(sub_builder, setter(custom))]
values: ValueList,
}
define_list_builder_accessors! {
struct OuterBuilder {
pub values: [u32],
}
}
/// Type alias for use by list builder macrology
pub type ValueList = Vec<u32>;
define_list_builder_helper! {
pub(crate) struct ValueListBuilder {
pub(crate) values: [u32],
}
built: ValueList = values;
default = vec![27];
item_build: |&value| Ok(value);
}
let mut builder = OuterBuilder::default();
assert_eq!{ builder.build().unwrap().values, &[27] }
builder.values().push(12);
assert_eq!{ builder.build().unwrap().values, &[27, 12] }
Macros
- Define accessor methods for a configuration item which is a list
- Define a list builder struct for use with
define_list_builder_accessors
Structs
- Error from trying to parse a MultilineListBuilder as a list of particular items
- List of
T
, a straightforward type, being built as part of the configuration
Enums
- Configuration item specifiable as a list, or a single multi-line string
Traits
- Extension trait, an alternative to
define_list_builder_helper