seaplane_cli/cli/cmds/formation/
land.rs1use clap::{ArgMatches, Command};
2
3use crate::{
4 api::FormationsReq,
5 cli::{
6 cmds::formation::SeaplaneFormationFetch,
7 errors,
8 validator::{validate_formation_name, validate_name_id},
9 CliCommand,
10 },
11 error::Result,
12 Ctx,
13};
14
15#[derive(Copy, Clone, Debug)]
16pub struct SeaplaneFormationLand;
17
18impl SeaplaneFormationLand {
19 pub fn command() -> Command {
20 let validator = |s: &str| validate_name_id(validate_formation_name, s);
21 Command::new("land")
22 .visible_alias("stop")
23 .about("Land (Stop) all configurations of a remote Formation Instance")
24 .arg(
25 arg!(name_id =["NAME|ID"] required)
26 .help("The name or ID of the Formation Instance to land")
27 .value_parser(validator),
28 )
29 .arg(
30 arg!(--all - ('a'))
31 .help("Stop all matching Formations even when FORMATION is ambiguous"),
32 )
33 .arg(arg!(--fetch|sync|synchronize - ('F')).help(
34 "Fetch remote Formation Instances and synchronize local Plan definitions prior to attempting to land",
35 ))
36 }
37}
38
39impl CliCommand for SeaplaneFormationLand {
40 fn run(&self, ctx: &mut Ctx) -> Result<()> {
41 if ctx.args.fetch {
42 let old_name = ctx.args.name_id.take();
43 ctx.internal_run = true;
44 SeaplaneFormationFetch.run(ctx)?;
45 ctx.internal_run = false;
46 ctx.args.name_id = old_name;
47 }
48 let name = ctx.args.name_id.as_ref().unwrap();
49 let indices = if ctx.args.all {
51 ctx.db.formations.formation_indices_of_left_matches(name)
52 } else {
53 ctx.db.formations.formation_indices_of_matches(name)
54 };
55
56 match indices.len() {
57 0 => errors::no_matching_item(name.to_string(), false, ctx.args.all)?,
58 1 => (),
59 _ => {
60 if !ctx.args.all {
61 errors::ambiguous_item(name.to_string(), true)?;
62 }
63 }
64 }
65
66 let mut req = FormationsReq::new_delay_token(ctx)?;
67 for idx in indices {
68 let formation = ctx.db.formations.get_formation_mut(idx).unwrap();
70 req.set_name(formation.name.as_ref().unwrap())?;
71
72 req.stop()?;
74
75 let ids: Vec<_> = formation.in_air.drain().collect();
77 for id in ids {
78 formation.grounded.insert(id);
79 }
80
81 ctx.persist_formations()?;
82
83 cli_print!("Successfully Landed remote Formation Instance '");
84 cli_print!(@Green, "{}", &name);
85 cli_println!("'");
86 }
87
88 Ok(())
89 }
90
91 fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
92 ctx.args.all = matches.get_flag("all");
93 ctx.args.name_id = matches.get_one::<String>("name_id").map(ToOwned::to_owned);
94 ctx.args.fetch = matches.get_flag("fetch");
95 Ok(())
96 }
97}