0

I am trying to make reimplementation of first 2 Final Fantasy games using original data from various platforms. I want to get 2 program arguments using the getopts crate and handle both of them by using match but it just executes the first match element. I think I screwed up something with types.

Maybe there is another way to do it? I am lost using the official Rust docs and any tutorials on internet are not really noob-friendly.

Here is the code:

let args: Vec<String> = env::args().map(|x| x.to_string()).collect();

if(args.len() < 3) {
    println!("=====ERROR=====\nInvalid number of parameters\nExpected: <gamename> <gamerom>\nType in: 'help me' to get some help.");
    process::exit(1);
}

let ref game = args[1];
let ref rom = args[2];

match game {
    help => {
        println!("=====HELP======");

        match rom {
            list => println!("Available games: ff1, ff2\nAvailable roms: ff1_j_msx, ff1_j_nes, ff1_u, ff1and2, ff2_j, ff2_u_proto"),
            me => println!("Available help commands:\nlist -> List of available games and roms.\nme -> This help"),
            _ => println!("=====ERROR=====\nInvalid help command.")
        }
    },
    _ => println!("=====ERROR=====\nInvalid game, type in 'help me' to get some help.") 
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
user160995
  • 129
  • 2
  • 1
    You don't use [getopts](https://doc.rust-lang.org/getopts/getopts/index.html) in your example. You want use it or not ? – Stargateur Jun 07 '17 at 09:48
  • 6
    Not an answer to your question, but an alternative library: [Clap](https://github.com/kbknapp/clap-rs#quick-example) is the most user-friendly command line parser I've seen in Rust. – Joe Clay Jun 07 '17 at 09:55
  • @Stargateur oops you are right :) I wanted to use it, but sometimes I forgot. – user160995 Jun 08 '17 at 06:02

1 Answers1

5

You really need to read the compilers error and warning messages. This code has seven warnings. If you had addressed any of them you'd be a lot closer to fixing the problem yourself. If you'd fixed all of them, your problem would be gone.

Here's a representative warning where the compiler tells you exactly what the problem is:

warning: unreachable pattern
  --> src/main.rs:24:5
   |
24 |     _ => println!("=====ERROR=====\nInvalid game, type in 'help me' to get some help.")
   |     ^ this is an unreachable pattern
   |
   = note: #[warn(unreachable_patterns)] on by default
note: this pattern matches any value
  --> src/main.rs:15:5
   |
15 |     help => {
   |     ^^^^

When you use just help, that creates a new variable with the value you are matching on. In this case, it matches everything, so the subsequent arms can never match.

Instead, you need to match against a string literal:

match game.as_str() {
    "help" => {
        match rom.as_str() {
            "list" => /* ... */,
            "me" => /* ... */,
            _ => /* ... */,
        }
    },
    _ => /* ... */,
}

I'd strongly encourage you to go back and re-read The Rust Programming Language. It's where a lot of the beginner documentation is kept. Specifically, you should read from the beginning and then up through the chapter on match and the chapter on patterns.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • The [readme](https://github.com/rust-lang/book/blob/master/README.md) on git repository of rust book say that "We recommend starting with the [second edition](http://rust-lang.github.io/book/second-edition).". – Stargateur Jun 07 '17 at 12:29
  • @Stargateur yep, it does. However, it's not fair to expect people to have read documentation that isn't linked from anywhere that they could reasonably have found it. After the release tomorrow, [the official documentation resources will point to the second book](https://doc.rust-lang.org/beta/book/), and I will have to go through thousands of SO answers to update links. – Shepmaster Jun 07 '17 at 12:50
  • Yeah, I had other warnings in a code and I didn't notice that (I will probably look carefully at these now). What I tried and messed up that I tried to convert these variables at some point to String type instead of str, as compiler clearly gave me message that it "^^^^^^^ expected struct `std::string::String`, found str" – user160995 Jun 08 '17 at 06:08