ephemeris_forge_forgejo/plan/
deploy_keys.rs1use ephemeris_forge::{Collection, FieldDiff, Report};
2
3use crate::Live;
4use crate::api::request::CreateKeyOption;
5use crate::config::DeployKeys;
6use crate::operation::deploy_keys::Operation;
7
8pub(super) fn plan(
11 config: Option<&DeployKeys>,
12 live: &Live,
13 report: &mut Report,
14) -> Vec<Operation> {
15 let Some(config) = config else {
16 return Vec::new();
17 };
18 let mut operations = Collection {
19 noun: "deploy key",
20 mode: config.mode,
21 }
22 .plan(
23 &config.keys,
24 &live.deploy_keys,
25 report,
26 |key, title| key.title.as_deref() == Some(title),
27 |title, desired, actual, _| {
28 let mut diff = FieldDiff::default();
29 diff.check(
30 "key",
31 actual
32 .is_some_and(|key| key.key.as_deref().is_some_and(|key| desired.matches(key))),
33 &actual.and_then(|key| key.key.as_deref()),
34 &desired.key,
35 );
36 diff.check(
37 "read_only",
38 actual.is_some_and(|key| key.read_only.unwrap_or(false) == desired.read_only),
39 &actual.map(|key| key.read_only.unwrap_or(false)),
40 &desired.read_only,
41 );
42 let mut operations = Vec::new();
43 if diff.has_changes() {
44 operations.extend(actual.map(|actual| Operation::Delete {
45 id: actual.id,
46 title: title.to_owned(),
47 }));
48 operations.push(Operation::Create {
49 body: CreateKeyOption::new(title, desired),
50 });
51 }
52 (diff, operations)
53 },
54 |key, _| {
55 let title = key.title.clone()?;
56 Some((title.clone(), Operation::Delete { id: key.id, title }))
57 },
58 );
59 operations.sort_by_key(|operation| !matches!(operation, Operation::Delete { id: _, title: _ }));
60 operations
61}