It doesn't seem like the derive_builder Builder pattern works all that well as used here:
it does not make optional pieces optional (everything but triple has a default)
it causes additional unit fields on the final Nyxstone type (Empty variable which holds the triple in the auto-generated NyxstoneBuilder. doesn't really make sense? A unit doesn't hold any information)
it mixes matters of the builder and the built
it makes reading/understanding the code harder than it needs to be
it needs an extra proc macro dependency, increasing compilation time
Instead, I'd propose to use an init/options struct instead, with the build/new function taking the triple directly:
let config = NyxstoneInit {
immediate_style: IntegerBase::HexPrefix,
...Default::default()
};
let nyxstone = Nyxstone::new("x86_64", config)?;
#[non_exhaustive] // optional, but would allow you to add more init options in the future by forcing the instantiator to use NyxstoneInit { field, ...Default::default() } to create the struct
#[derive(Debug, Default)] // all fields impl Default!
pub struct NyxstoneInit<'a> {
pub cpu: Option<&'a str>, // .unwrap_or("") in `Nyxstone::new` to get the current behavior
pub enabled_features: Vec<String>,
pub disabled_features: Vec<String>,
pub immediate_style: IntegerBase,
}
impl NyxstoneInit<'_> {
pub fn with_feature(mut self, feature: &str) -> Self { ... } // note how these can still take self by value if you want
pub fn without_feature(mut self, feature: &str) -> Self { ... }
pub fn init(self, target_triple: &str) -> Result<Nyxstone, NyxstoneInitError> {
Nyxstone::new(target_triple, self)
}
}
pub struct Nyxstone {
// all the useless fields gone
inner: cxx::UniquePtr<ffi::NyxstoneFFI>,
}
impl Nyxstone {
pub fn new(target_triple: &str, options: NyxstoneInit<'_>) -> Result<Self, NyxstoneInitError> {
// do the init
}
}
It doesn't seem like the
derive_builder
Builder pattern works all that well as used here:triple
has a default)Nyxstone
type (Empty variable which holds the triple in the auto-generated NyxstoneBuilder.
doesn't really make sense? A unit doesn't hold any information)Instead, I'd propose to use an init/options struct instead, with the
build
/new
function taking the triple directly: