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