add documentation

This commit is contained in:
zekro committed 2026-07-26 23:52:26 +02:00
1 parent c367d3f3ca
commit 45fbc088ba
5 files changed
+101

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
# 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 {
| ^^^^
```