Pass argument with match


#1

Is it possible to pass an argument when using match?
I would like command variable to match “AddUser somenewuser”

Can I pass argument with the addUser command and pass the argument back to the add() function? I have some code looking like this now:

io::stdin().read_line(&mut command);
    match command.trim(){
    "AddUser" => add(),

#2

Ah I missed the second line in your post. My apologies.

No you can’t match parts of a string literal without first doing some processing. I think it’s best to split the string using split_whitespace, and then process the tokens.

Yes certainly! I’ve made a little program, hopefully the comments help:

use std::io;

/// This function borrows a str and prints it.
fn print(s: &str) {
    println!("You entered: '{}'", s);
}

fn main() {
    let mut command = String::new(); // initializes `command` as an empty String

    println!("Enter a command:");

    // In the next line, the `read_line` function *borrows* the `command` variable
    // We still have "ownership" over it, i.e. this `main` function will be the one
    // freeing the memory of the String.
    //
    // Since it is a *mutable borrow* (the `mut` part of `&mut`), that allows the
    // `read_line` function to modify the String.
    let result = io::stdin().read_line(&mut command);

    // We should check that result is okay
    if result.is_err() {
        panic!("Oh no something went wrong");
    }

    // If we reach here, then we know result is Ok!

    // Now we check the contents of `command`
    match command.trim() {
        // The `&command` bit in the next line is an ergonomic part of Rust
        // `command` is a String, and &command means pass a String reference (&String)
        //
        // Since the String type implements Deref<Target = str>, &String is
        // automatically coerced to &str. See the following link:
        //
        // https://doc.rust-lang.org/std/string/struct.String.html#deref
        "AddUser" => print(&command),
        _ => {} // do nothing
    };
}

#3

The way you’d use @azriel91’s suggestion is:

fn main() {
    let input = "AddUser foo";
    let mut tokens = input.split_whitespace();
    match (tokens.next(), tokens.next()) {
        (Some("AddUser"), Some(name)) => add(name),
        x => println!("something else: {:?}", x),
    }
}

fn add(name: &str) {
    println!("Adding {}", name);
}

You can add more match arms to handle specific cases (eg unknown cmd, known cmd but missing argument, etc).