use crate::logging::FactsEmitter;
use crate::types::ids::{action_id, plan_id};
use crate::types::{Action, Plan, PlanInput};
use crate::logging::audit::{new_run_id, AuditCtx, AuditMode};
use crate::logging::StageLogger;
pub(crate) fn build<E: FactsEmitter, A: crate::logging::AuditSink>(
api: &super::Switchyard<E, A>,
input: PlanInput,
) -> Plan {
let mut actions: Vec<Action> = Vec::new();
for l in input.link {
actions.push(Action::EnsureSymlink {
source: l.source,
target: l.target,
});
}
for r in input.restore {
actions.push(Action::RestoreFromBackup { target: r.target });
}
actions.sort_by(|a, b| {
let ka = match a {
Action::EnsureSymlink { target, .. } => {
(0u8, target.rel().to_string_lossy().to_string())
}
Action::RestoreFromBackup { target } => {
(1u8, target.rel().to_string_lossy().to_string())
}
};
let kb = match b {
Action::EnsureSymlink { target, .. } => {
(0u8, target.rel().to_string_lossy().to_string())
}
Action::RestoreFromBackup { target } => {
(1u8, target.rel().to_string_lossy().to_string())
}
};
ka.cmp(&kb)
});
let plan = Plan { actions };
let pid_uuid = plan_id(&plan);
let pid = pid_uuid.to_string();
let run_id = new_run_id();
let tctx = AuditCtx::new(
&api.facts,
pid.clone(),
run_id,
crate::logging::TS_ZERO.to_string(),
AuditMode {
dry_run: true,
redact: true,
},
);
let slog = StageLogger::new(&tctx);
for (idx, act) in plan.actions.iter().enumerate() {
let aid = action_id(&pid_uuid, act, idx).to_string();
let path = match act {
Action::EnsureSymlink { target, .. } | Action::RestoreFromBackup { target } => {
Some(target.as_path().display().to_string())
}
};
if let Some(p) = path {
slog.plan().action_id(aid).path(p).emit_success();
} else {
slog.plan().action_id(aid).emit_success();
}
}
plan
}