I noticed that I did something apparently unconventional when I wrote my last builder. I made the configuration methods take &mut self, but the terminal method self. Do you think that is an acceptable pattern?
The API guidelines have two different types of builders:
non-consuming: &mut self for configuration, &self for the terminal method
consuming: mut self for configuration, self for terminal method
What do you think about my pattern, &mut self with self terminal? At least superficially it seems legitimate, you have a builder, you configure it by mutating its fields, and finally consume it without having to clone anything …?
And that's why my usual advice (@anon4807959) is to just take (and return) self by value in the configuration methods as well. In this case you can't accidentally reuse the builder, but method chaining still works.
Alternatively, if you do want to be able to reuse a configured builder, then build() should probably take &self.
This is not an advice but FYI: builders taking &mut self can be written in similar way to method chaining, by cascade! macro by cascade crate.
(Thanks to this macro, I think it is primarily important whether the builder can be reused or not, rather than whether it is easy to write or not.)