We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors Are Values step 21 of 24
#[must_use] in depth
Repair a builder API's annotations and make its port updates take effect.
pub fn build(ops: Vec<String>) -> Vec<String>
Start with host localhost and port 80. Process operations in order:
| Operation | State change | Output appended |
|---|---|---|
port:N |
Set port from N | None |
host:H |
Set host to H exactly | None |
reset |
Restore localhost and 80 | None |
show |
None | {host}:{port} |
validate |
None | ok {host}:{port} or err {message} |
| Anything else | None | unknown |
Parse N with Rust's str::parse::<u16>(). Failed parsing, including empty,
negative, out-of-range or whitespace-padded input, sets the port to zero.
A leading + is accepted. Host text may be empty or contain colons; keep
the entire suffix after host: without trimming.
Validation checks the host first. An empty host produces
host must not be empty. Otherwise, a port below 1024 produces
port {port} is privileged, using the current port. All other configurations
pass. This is the exercise's validation policy; it does not test network
connectivity, hostname syntax or operating-system permissions.
For example, ["show", "port:8080", "validate", "reset", "show"] returns
["localhost:80", "ok localhost:8080", "localhost:80"].
Empty input returns an empty vector. Validation leaves the current settings
available for later operations.
Repair the discarded builder result
with_port and with_host consume a Config and return its replacement.
Keep their #[must_use] attributes. The starter's port branch calls the
method on a clone and discards the returned configuration, so the original
cfg never changes.
Assign the returned value back to cfg, as the host branch already does.
No clone is needed there because the old configuration is being replaced.
The clone before validate serves a different purpose: validation consumes
its receiver, while later operations still need the current configuration.
Remove two unnecessary function annotations
The starter has four annotated methods. Keep the annotations on the two
builder methods and remove the bare attributes on validate and reset:
| Method | Reason |
|---|---|
validate |
Its Result return type already warns when directly discarded; a bare function attribute triggers Clippy's double_must_use lint |
reset |
It changes the existing configuration and returns unit; annotating that return triggers Clippy's must_use_unit lint |
A custom #[must_use = "explanation"] message can add context to an API,
but this exercise needs no extra function annotation on validate.
What the type annotation means
Keep #[must_use] on Validated. This asks the compiler to warn when a
value of that type is directly discarded in an expression statement.
The warning follows the type, so producers do not each need an annotation.
A function annotation instead targets that function's returned value.
These are warnings about likely mistakes, not proof that a result was
meaningfully handled. Binding a value or explicitly writing let _ = ...
can suppress a must-use diagnostic without applying its contents. Silencing
the warning in the broken port branch would not fix its output.
In particular, ignoring an error deliberately is different from handling it. For this task, match the validation result and append the required success or error message.
Attribute placement and lint limits
An attribute on a trait method declaration can apply to calls to its
implementations. Putting #[must_use] only on the method inside a trait
implementation has no effect. An attribute on a trait can also affect
values returned through impl Trait or a trait object.
The unused_must_use lint does not recursively enforce use of everything
stored inside every container. Do not rely on wrapping a result to communicate
intentional error handling. Prefer code that makes the chosen action clear.
With warnings denied, applicable must-use and Clippy warnings fail the submission gate. Passing that gate still does not establish correct behavior; the operation results must also match the task.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.