# Solution 2: "Builder Pattern" A better solution is to use two different structs for each state with their separate implementations. That ensured on a compiler level that the manager can not be misused in either state it is. ```rust let pw = LockedCredentialManager::new(); pw.set("foo", "bar"); ``` This produces the following compiler error: ``` error[E0599]: no method named `set` found for struct `LockedCredentialManager` in the current scope --> 03-builder-pattern\src\main.rs:45:8 | 5 | struct LockedCredentialManager { | ------------------------------ method `set` not found for this struct ... 45 | pw.set("foo", "bar"); | ^^^ method not found in `LockedCredentialManager` ``` And because we pass the struct by reference in the `unlock` and `lock` methods, resulting from Rust's [onwership memory model](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html), the previous object can not be used after the transformation. And because this is checked at compile time, it makes the double locking and unlocking a non-issue in production. Let's see what the following code results in. ```rust let pw = LockedCredentialManager::new(); let mut pw = pw.unlock("pssst"); pw.lock(); pw.lock(); ``` This code results in the following compiler error: ``` error[E0382]: use of moved value: `pw` --> 03-builder-pattern\src\main.rs:49:5 | 45 | let mut pw = pw.unlock("pssst"); | ------ move occurs because `pw` has type `UnlockedCredentialManager`, which does not implement the `Copy` trait ... 48 | pw.lock(); | ------ `pw` moved due to this method call 49 | pw.lock(); | ^^ value used here after move | note: `UnlockedCredentialManager::lock` takes ownership of the receiver `self`, which moves `pw` --> 03-builder-pattern\src\main.rs:36:17 | 36 | pub fn lock(self) -> LockedCredentialManager { | ^^^^ ```