seaplane_cli/cli/cmds/flight/
edit.rs

1use clap::{ArgMatches, Command};
2
3use crate::{
4    cli::{
5        cmds::flight::{
6            common::{self, SeaplaneFlightCommonArgMatches},
7            IMAGE_SPEC,
8        },
9        errors::wrap_cli_context,
10        validator::{validate_flight_name, validate_name_id},
11        CliCommand,
12    },
13    context::{Ctx, FlightCtx},
14    error::Result,
15};
16
17#[derive(Copy, Clone, Debug)]
18pub struct SeaplaneFlightEdit;
19
20impl SeaplaneFlightEdit {
21    pub fn command() -> Command {
22        let validator = |s: &str| validate_name_id(validate_flight_name, s);
23        // TODO: add --no-maximum or similar
24        // TODO: add --from
25        Command::new("edit")
26            .about("Edit a local Flight Plan")
27            .after_help(IMAGE_SPEC)
28            .arg(
29                arg!(name_id required =["NAME|ID"])
30                    .help("The source name or ID of the Flight Plan to edit")
31                    .value_parser(validator),
32            )
33            .arg(arg!(--exact - ('x')).help("The given name or ID must be an exact match"))
34            .args(common::args(false))
35    }
36}
37
38impl CliCommand for SeaplaneFlightEdit {
39    fn run(&self, ctx: &mut Ctx) -> Result<()> {
40        if ctx.args.stateless {
41            cli_eprint!(@Red, "error: ");
42            cli_eprint!("'");
43            cli_eprint!(@Yellow, "--stateless");
44            cli_eprint!("' cannot be used with '");
45            cli_eprint!(@Yellow, "seaplane flight edit");
46            cli_eprintln!("'");
47            cli_eprintln!("(hint: 'seaplane flight edit' only modifies local plans)");
48            cli_eprint!("(hint: you may want 'seaplane ");
49            cli_eprint!(@Green, "formation ");
50            cli_eprintln!("edit' instead)");
51            std::process::exit(1);
52        }
53        let flights = &mut ctx.db.flights;
54
55        // Now we just edit the newly copied Flight to match the given CLI params...
56        // name_id cannot be None in `flight edit`
57        if let Err(e) = flights.update_flight(
58            ctx.args.name_id.as_ref().unwrap(),
59            ctx.args.exact,
60            ctx.flight_ctx.get_or_init(),
61        ) {
62            return wrap_cli_context(e, ctx.args.exact, false);
63        }
64
65        ctx.persist_flights()?;
66
67        cli_print!("Successfully edited Flight Plan '");
68        cli_print!(@Yellow, "{}", ctx.args.name_id.as_ref().unwrap());
69        cli_println!("'");
70
71        Ok(())
72    }
73
74    fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
75        // clap will not let "source" be None
76        ctx.args.name_id = matches.get_one::<String>("name_id").map(ToOwned::to_owned);
77        ctx.flight_ctx
78            .init(FlightCtx::from_flight_common(&SeaplaneFlightCommonArgMatches(matches), ctx)?);
79        Ok(())
80    }
81}