I'm learning rust and would like to better understand what is happening here. I have the following declared:
pub struct SomeHandler {}
impl SomeHandler {
pub fn configure(&self, app: &App) {
app.subcommand(
SubCommand::with_name("server-status")
.about("Displays the status of the server")
);
}
pub fn check_match(&self, matches: &ArgMatches) -> bool {
matches.subcommand_matches("server-status").is_some()
}
pub fn handle(&self, arg_match: &ArgMatches) {
...
}
}
And then in main.rs
I'm calling it like this:
let mut app = App::new("My CLI")
.author("Author <author@email.com>")
.version("0.1.0")
.about("Command line interface app");
let myhandler = SomeHandler {};
myhandler.configure(&app);
let matches = app.get_matches();
let matched = myhandler.check_match(&matches);
if !matched {
eprintln!("None of the commands match the provided args.");
process::exit(1);
}
myhandler.handle(&matches);
process::exit(0);
But I get the following error:
error[E0507]: cannot move out of `*app` which is behind a shared reference
--> cli\src\some_handler.rs:15:9
|
15 | app.subcommand(
| ^^^ move occurs because `*app` has type `App<'_, '_>`, which does not implement the `Copy` trait
How do I fix this error? Is there a better way to handle this? I'm trying to build a command line application in rust with multiple commands and options. I don't want to implement it all in a single file. What is a good pattern to follow here?
Any help would be great,
Thanks, Manthan
The subcommand()
method consumes the app and returns a new one. This nicely supports chaining, but requires your configure
function to also accept an object, and also to return one:
pub fn configure(&self, app: App<'static, 'static>) -> App<'static, 'static> {
app.subcommand(
SubCommand::with_name("server-status")
.about("Displays the status of the server")
)
}
// and in main:
app = myhandler.configure(app);
It's also possible for configure
to take a reference, but then that has to be a mut
reference, and you have to call mem::replace
to extract the Clap
out of the reference, leaving a dummy in its stead, and finally assign it back. If you're really curious, take a look at it here.