Simplify argument parsing default value

Hi, I'm writing a new CLI tool and I'm using clap-rs for argument parsing.

In this tool you can specify in which port you wan't to listen TCP connections using the "-p PORT" flag. As you know, ports range is from 0 to 2^16. If the user put something out of this range I wan't to notify it through an error message and set port value to 8080.

This is my code:

My question is: Is there a better way to achieve this ?

You can slightly simplify this pattern using unwrap_or_else:

let port: u16 = p.parse().unwrap_or_else(|_| {
    eprintln!("specified port isn't in a valid range, setting to 8080");
    8080
});

Note 1: By the way, I would recommend against doing this. Specifying an invalid port number is an error, probably a typo or something, and falling back to a completely different (albeit valid) port number is going to be the source of many hours of head-banging against the table for the one running into this behavior. So I'd just report it as an error.

Note 2: Not sure how fine control you need over the arguments, but for cutting down on value extraction boilerplate, I'd suggest you to use structopt instead of directly using clap.

Thank you very much for the tips and for the code simplification, I will keep them in mind.

Again, thank you!

1 Like

I agree with @H2CO3 that some broader changes might be best. But for the sake of comparison, here's a version that preserves all the original behavior but reduces some nesting and duplication. (Though I often find explicit match more readable than and/or combinators, so it's fine if you prefer the original code.)

let port: u16 = matches.value_of("port").and_then(|p|
    p.parse().ok().or_else(|| {
        eprintln!("specified port isn't in a valid range, setting to 8080");
        None
    })
).unwrap_or(8080);
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.