We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Shape Your Data: Structs, Enums, Pattern Matching step 2 of 26
Field init shorthand and struct update syntax
Start with a host and port, apply overrides in input order, then return the final values joined by a colon.
pub fn apply_overrides(
base_host: String,
base_port: u32,
overrides: Vec<(String, String)>,
) -> String
Override rules
| Key | Behavior |
|---|---|
host |
Replace the host with the value exactly as supplied. |
port |
Replace the port if the value parses as u32; otherwise leave the current port unchanged. |
| Any other key | Ignore the pair. |
Keys are case-sensitive and are not trimmed. Later valid overrides replace earlier ones. An invalid port does not undo an earlier valid port override. An empty list leaves both base values unchanged.
Port parsing accepts ASCII decimal digits, optionally preceded by +,
within 0..=4294967295. Leading zeros are allowed. Empty strings, negative
signs, whitespace, underscores, hexadecimal notation and overflow are
rejected. Use value.parse::<u32>() without trimming.
Hosts may be empty or contain spaces, colons or Unicode. Do not validate or
normalize them. This is a string-and-integer exercise, not network-address
validation: ports above 65535 are accepted if they fit in u32.
Format the result as host:port, with the port in ordinary decimal notation.
For example, base ("localhost", 8080) and overrides
[("host", "b.test"), ("port", "+002"), ("port", "bad")] produce
"b.test:2". An empty host and port zero produce ":0".
Field shorthand and struct updates
Use a Config with host: String and port: u32. Practice rebuilding it
after an override using struct update syntax. Assigning fields directly
could produce the same output; the harness checks results rather than
enforcing a particular syntax.
When a local variable and a field have the same name, Config { host, port }
abbreviates Config { host: host, port: port }. To replace selected fields,
list their new values and end with ..base for the remaining fields.
The base expression comes last, without a trailing comma.
This complete example demonstrates both forms:
struct Config {
host: String,
port: u32,
}
fn main() {
let host = String::from("localhost");
let port = 8080;
let base = Config { host, port };
let updated = Config { port: 9000, ..base };
assert_eq!(updated.host, "localhost");
assert_eq!(updated.port, 9000);
// The replaced field was not taken from the base.
assert_eq!(base.port, 8080);
}
Which fields move?
Struct update uses the explicitly supplied values and moves or copies only
the omitted fields from the base. Here host is omitted, so the new config
takes ownership of base.host. The port field is explicitly replaced;
it is not copied from base in this expression.
The starter tries to take base.host twice, producing E0382. After the
first update, base.host is no longer available. Other initialized fields
can still be accessed, but the partially moved base cannot be used as a
whole value. Types implementing Drop have additional restrictions on
moving out individual non-Copy fields.
If an omitted field is Copy, the update copies it and leaves it available
in the base. Replacing the host while inheriting the port therefore keeps
the old host usable:
struct Config {
host: String,
port: u32,
}
fn main() {
let base = Config { host: "old.test".into(), port: 443 };
let updated = Config { host: "new.test".into(), ..base };
assert_eq!(updated.host, "new.test");
assert_eq!(updated.port, 443);
assert_eq!(base.host, "old.test");
assert_eq!(base.port, 443);
}
Reference-valued fields can also be copied when their reference type is
Copy, such as &str. Struct update does not require every struct to own
all its data. This exercise uses an owned String, so carry one config
forward through the override loop instead of repeatedly using an old base.
Cloning is another option when a type implements Clone, but it is not
needed here. A derived clone of this config would clone its String too;
the storage cost depends on the string rather than a fixed allocation
charge for every use of struct update.
Apply one override at a time
Match key.as_str() against string literals. A literal pattern such as
"host" is a &str pattern and cannot directly match a String value.
For a host override, supply the new host and inherit the port. For a valid
port override, supply the parsed port and inherit the host. On a parse
error or unknown key, keep the current config.
Clippy's redundant_field_names flags repeated names that can use shorthand.
needless_update flags an update where every field is already supplied,
so the base contributes no fields. Fix these diagnostics rather than
suppressing them. Submissions must compile, produce the expected output
and pass the runner's Clippy checks.
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.