use super::{AS, StartError, verb_ok};
use crate::actions::verbs::{self, log_step_failure};
use crate::binding::work_worktree_path;
use crate::cli_outbound::Cli;
use crate::opslog::Origin;
use std::path::{Path, PathBuf};
const CLAIM: &str = "claim";
const DRIFT: &str = "cross-check";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ClaimResolved {
pub worktree: PathBuf,
pub suffixed: bool,
}
pub fn execute_claim(
bl: &Cli,
state_root: &Path,
ts: &str,
project: &Path,
id: &str,
name: &str,
balls_state_root: &Path,
) -> Result<ClaimResolved, StartError> {
let out = verb_ok(
verbs::run_logged(
bl,
state_root,
ts,
project,
&[CLAIM, id, AS, name],
Origin::Balls,
)?,
CLAIM,
)?;
cross_check_claim(&out.stdout, balls_state_root, project, id, name).inspect_err(|err| {
let _ = log_step_failure(
state_root,
ts,
project,
DRIFT,
&err.to_string(),
Origin::Balls,
bl.client(),
);
})
}
pub fn cross_check_claim(
stdout: &str,
balls_state_root: &Path,
project: &Path,
id: &str,
name: &str,
) -> Result<ClaimResolved, StartError> {
let got = PathBuf::from(stdout.trim());
let canonical = work_worktree_path(balls_state_root, project, id, None);
let suffixed = work_worktree_path(balls_state_root, project, id, Some(name));
if got == canonical {
return Ok(ClaimResolved {
worktree: canonical,
suffixed: false,
});
}
if got == suffixed {
return Ok(ClaimResolved {
worktree: suffixed,
suffixed: true,
});
}
let err = StartError::Drift {
stdout: got.display().to_string(),
canonical: canonical.display().to_string(),
suffixed: suffixed.display().to_string(),
};
Err(err)
}