use std::sync::Arc;
use super::super::row;
use super::{Move, PilotCtx};
use crate::app::Snapshot;
use crate::board::BoardRow;
use crate::boundary::Action;
use crate::boundary::dispatch::{self, Deps};
use crate::opslog;
use crate::start::{BallSpec, Payload};
use crate::ui_state::UiState;
impl PilotCtx {
pub(super) fn fire(
&self,
snapshot: &Arc<Snapshot>,
ui: &mut UiState,
ts: &str,
workspace: &std::path::Path,
one: &Move,
) -> bool {
let deps = self.deps(snapshot);
let entry = match one {
Move::Reap {
row,
claimant,
since,
} => {
if !release(&deps, ui, ts, row, claimant) {
return false;
}
row::reaped(ts.to_owned(), workspace, &row.id, claimant, since)
}
Move::Spawn { row } => {
let Some(conversation) = Self::birth(&deps, ui, ts, workspace, row) else {
return false;
};
row::spawned(ts.to_owned(), workspace, &row.id, &conversation)
}
};
let _ = opslog::append(&deps.state_root, &entry);
true
}
fn birth(
deps: &Deps,
ui: &mut UiState,
ts: &str,
workspace: &std::path::Path,
row: &BoardRow,
) -> Option<String> {
let project = deps.snapshot.project_path(&row.project).ok()?;
let ball = deps
.snapshot
.balls_by_project
.get(&project)?
.iter()
.find(|b| b.id == row.id)?;
let payload = Payload::Ball {
project: row.project.clone(),
ball: BallSpec::Existing {
id: ball.id.clone(),
title: ball.title.clone(),
body: ball.body.clone(),
join: row.state,
tags: ball.tags.clone(),
},
};
let prepared = dispatch::prepare(deps, ts, workspace, &project, &payload).ok()?;
let goal = prepared.goal.clone();
let fired = dispatch::prompt(deps, ui, ts, workspace, &prepared, &goal, None);
if fired.is_err() {
release(deps, ui, ts, row, &crate::naming::leaf(workspace));
}
fired.ok()
}
fn deps(&self, snapshot: &Arc<Snapshot>) -> Deps {
Deps {
snapshot: Arc::clone(snapshot),
..self.deps.clone()
}
}
}
fn release(deps: &Deps, ui: &mut UiState, ts: &str, row: &BoardRow, name: &str) -> bool {
released(dispatch::dispatch(
deps,
ui,
ts,
&Action::Ball(crate::actions::verbs::Verb::Release {
project: row.project.clone(),
id: row.id.clone(),
name: name.to_owned(),
}),
))
}
fn released(reply: Result<crate::boundary::reply::Reply, String>) -> bool {
matches!(reply, Ok(crate::boundary::reply::Reply::Outcome(o)) if o.ok())
}