FRU Syntax vs Builder Pattern in Rust

A short comparison of FRU vs Builder Pattern

Both the Functional Record Update (FRU) Syntax in Rust and the Builder Pattern can be used somewhat interchangeably. There are merits and demerits for each, so we will draw a comparison here. If you want the short summary, my opinion is that I prefer the FRU syntax unless you require a complex constructor or have some other setup/teardown that can only be solved with the Builder Pattern.

What is FRU?

FRU is a special syntax in Rust that allows for a subset of fields to be updated, with the rest of the fields filled in from an object of the same type.

#[derive(Default)]
pub struct ABC {
   pub a: u64,
   pub b: u64,
   pub c: u64,
}

fn main() {
   let a = ABC { a:1, b:2, c:3 };
   let _ = ABC { a:2, ..a };
   let _ = ABC { a:3, ..std::default::Default::default() };
}

How does FRU compare?

The best part about FRU is that it is concise and works well with Default. Default itself can be derived, so both the code size and complexity is low.

When would builder be appropriate

If your struct requires any sort of action to take place as part of initialization then a builder pattern is appropriate. Think of a builder as two steps, the first steps are configuration of how you want your object to be built, and the second step is for the object to be initialized, instantiated, and constructed. You may have live resources like a socket connection that needs initialization or you may have hidden data as in private fields. Either way, any sort of hidden complexity is very appropriate for usage with the builder pattern.