use super::AppModel;
use crate::projects::balls::Ball;
use crate::projects::join::JoinRow;
use crate::start::{self, BallSpec, Payload, StartInputs, Target};
use std::path::{Path, PathBuf};
impl AppModel {
fn ball_of(&self, project: &Path, id: &str) -> Option<&Ball> {
self.balls_by_project
.get(project)?
.iter()
.find(|b| b.id == id)
}
fn start_target(&self) -> Target {
match self.focus.ws.as_deref() {
Some(ws) => Target::Existing {
workspace: ws.to_path_buf(),
},
None => Target::Mint,
}
}
pub fn claimants(&self) -> Vec<String> {
self.balls_by_project
.values()
.flatten()
.filter_map(|b| b.claimant.clone())
.collect()
}
fn start_inputs_at(&self, target: Target, payload: Payload) -> StartInputs {
StartInputs {
target,
payload,
home: self.roots.home.clone(),
yog_data_root: self.roots.yog_data.clone(),
balls_state_root: self.balls_state_root(),
claimants: self.claimants(),
}
}
fn start_inputs(&self, payload: Payload) -> StartInputs {
self.start_inputs_at(self.start_target(), payload)
}
pub fn start_bare_inputs(&self) -> StartInputs {
self.start_inputs(Payload::Bare)
}
pub fn new_workspace_inputs(&self) -> StartInputs {
self.start_inputs_at(Target::Mint, Payload::Bare)
}
pub fn start_path_inputs(&self, dir: &Path) -> StartInputs {
self.start_inputs(Payload::Path {
dir: dir.to_path_buf(),
})
}
pub fn startable(&self) -> Vec<StartInputs> {
self.join_rows
.iter()
.filter(|r| start::is_start_eligible(r.state))
.filter_map(|row| Some(self.start_inputs(self.ball_payload(row)?)))
.collect()
}
pub fn resumable(&self) -> Vec<StartInputs> {
self.join_rows
.iter()
.filter(|r| start::is_resume_eligible(r.state))
.filter_map(|row| {
let workspace = row.workspace.clone()?;
Some(self.start_inputs_at(Target::Existing { workspace }, self.ball_payload(row)?))
})
.collect()
}
fn ball_payload(&self, row: &JoinRow) -> Option<Payload> {
let ball = self.ball_of(&row.project, &row.ball_id)?;
Some(Payload::Ball {
project: row.project.clone(),
ball: BallSpec::Existing {
id: row.ball_id.clone(),
title: ball.title.clone(),
body: ball.body.clone(),
join: row.state,
},
})
}
pub fn new_ball_inputs(&self, project: &Path, title: &str, body: &str) -> StartInputs {
self.start_inputs(Payload::Ball {
project: project.to_path_buf(),
ball: BallSpec::New {
title: title.to_owned(),
body: body.to_owned(),
},
})
}
pub fn project_paths(&self) -> Vec<PathBuf> {
let mut ps: Vec<PathBuf> = self.balls_by_project.keys().cloned().collect();
ps.sort();
ps
}
}