A modified builder pattern in Rust

⚓ Rust    📅 2026-03-29    👤 surdeus    👁️ 9      

surdeus

Usually the pattern looks like:

 let mut builder = Builder::new();
builder.set_attr1(2).set_attr2("doc");
let target = builder.build();
target.use();

However, as C++ programmer, I like to skip build phase, and start using the built object right after setting all required attributes, as:

let mut target = Builder::new();
target.set_attr1(2).set_attr2("doc").use();

There is no problem in Rust too besides that set_ functions get builder/target self as &mut, and use function should take self
as &mut too, because build() is a hidden part of use(). Using mut creates a problem of nested calls of the target object, for example:

let mut cli = CLI::new();
cli.set_opt("n");
....
    if let Some(OptVal::Str(name)) = cli.get_opt("n") {
        let name = name.clone(); // to avoid using nested mut borrowing
        for _ in 0..if let Some(OptVal::Num(count)) = cli.get_opt("c")
            && *count > 0
        {
            *count
        } else {
            1
        } {
            println!("Hello {name}!");
        }
    } else {
        eprintln!("{}", cli.get_description().unwrap())
    }

Is there an elegant way to make calls of get_opt() without using mut self?

A complete real world example is here.

2 posts - 2 participants

Read full topic

🏷️ Rust_feed