In Rust, how should related structures be grouped so that the function signature can accept several different types, referring to a specific type inside the method body?
The following example is for simplicity:
enum Command { Increment {quantity: u32}, Decrement {quantity: u32}, } fn process_command(command: Command) { match command { Command::Increment => increase(command), Command::Decrement => decrease(command), }; } fn increase(increment: Command::Increment) { println!("Increasing by: {}.", increment.quantity); } fn decrease(decrement: Command::Decrement) { println!("Decreasing by: {}.", decrement.quantity); } fn main() { let input = "Add"; let quantity = 4; let command: Command = match input { "Add" => Command::Increment { quantity: quantity }, "Subtract" => Command::Decrement { quantity: quantity }, _ => unreachable!(), }; process_command(command); }
Compiling results in the following two errors:
src/main.rs:13:24: 13:42 error: found value name used as a type: DefVariant(DefId { krate: 0, node: 4 }, DefId { krate: 0, node: 5 }, true) [E0248] src/main.rs:13 fn increase(increment: Command::Increment) { ^~~~~~~~~~~~~~~~~~ src/main.rs:17:24: 17:42 error: found value name used as a type: DefVariant(DefId { krate: 0, node: 4 }, DefId { krate: 0, node: 8 }, true) [E0248] src/main.rs:17 fn decrease(decrement: Command::Decrement) { ^~~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors
If I declare the structures separately and wrap the structures inside the struct tuples (correct terminology?) Each within the enum, then I get the expected result, but with verbosity and similar type names everywhere, I suspect that I misunderstood:
struct Increment { quantity: u32, } struct Decrement { quantity: u32, } enum Command { Increment(Increment), Decrement(Decrement), } fn process_command(command: Command) { match command { Command::Increment(increment) => increase(increment), Command::Decrement(decrement) => decrease(decrement), }; } fn increase(increment: Increment) { println!("Increasing by: {}.", increment.quantity); } fn decrease(decrement: Decrement) { println!("Decreasing by: {}.", decrement.quantity); } fn main() { let input = "Add"; let quantity = 4; let command: Command = match input { "Add" => Command::Increment(Increment { quantity: quantity }), "Subtract" => Command::Decrement(Decrement { quantity: quantity }), _ => unreachable!(), }; process_command(command); }
Output Launch:
Increasing by: 4.
Is packaging the structure as an enumeration (terminology?) Sharing the same name really the best solution? Command::Increment(Increment { quantity: 7 })