Builder pattern in Rust: self vs. &mut self, and method vs. associated function

Thank you very much for teaching me the typestate builder pattern.

I applied the knowledge (hopefully correct), and created these builders:

  • EnvBuilder to set options for opening an LMDB environment. A path must be set before the environment can be opened (not setting a path results in a compile-time error).
  • DbOptions specifying the options and name of a database inside the environment. Unless a name has been set (or the "unnamed" database has been selected), the builder cannot be used to open a database (again, with checks performed at compile-time). Additionally, certain methods (currently DbOptions::reversedup to select that values are sorted in reverse order) are only available when certain other options have been selected (namely DbOptions::keys_duplicate, which permits that a key may have multiple values at all).

Beside gaining these extra checks at compile-time, I also need to consume self because the type of DbOptions will change during building. DbOptions comes with type arguments that reflect the stored types inside the database (methods DbOptions::key_type and value_type). The methods setting the types will need to store a type inside the builder, rather than a value. Making the methods take &mut self won't work here.

Thus, I ended up making my builder consuming self – for multiple reasons.