use super::model::Workspace;
use crate::task::Task;
use crate::workflow::Workflow;
impl Workspace {
pub fn done_steps(&self, task: &Task) -> Vec<String> {
match self.workflow(&task.workflow_name) {
Some(workflow) => done_steps(task, workflow),
None => Vec::new(),
}
}
pub fn next_step(&self, task: &Task) -> Option<String> {
let workflow = self.workflow(&task.workflow_name)?;
next_step(task, workflow)
}
pub fn state_line(&self, task: &Task) -> String {
let Some(workflow) = self.workflow(&task.workflow_name) else {
return format!("工作区里没有这条工作流:{}", task.workflow_name);
};
state_line(task, workflow)
}
}
fn done_steps(task: &Task, workflow: &Workflow) -> Vec<String> {
let names = workflow.step_names();
let mut verdict: Vec<(String, bool)> = Vec::new();
for event in &task.journal {
let (step, extra) = match event.step.split_once('·') {
Some((step, rest)) => (step.to_string(), Some(rest.to_string())),
None => (event.step.clone(), None),
};
if !names.contains(&step) {
continue;
}
match verdict.iter_mut().find(|(name, _)| *name == step) {
Some((_, last)) => {
if extra.is_some() {
*last = *last && event.ok;
} else {
*last = event.ok;
}
}
None => verdict.push((step, event.ok)),
}
}
verdict
.into_iter()
.filter(|(_, ok)| *ok)
.map(|(name, _)| name)
.collect()
}
fn next_step(task: &Task, workflow: &Workflow) -> Option<String> {
let finished = done_steps(task, workflow);
workflow
.step_names()
.into_iter()
.find(|name| !finished.contains(name))
}
fn state_line(task: &Task, workflow: &Workflow) -> String {
let names = workflow.step_names();
if names.is_empty() {
return format!("这条工作流没有步骤:{}", workflow.name);
}
match next_step(task, workflow) {
Some(step) => format!("下一步:{step}"),
None => format!("{} 个步骤都走过了", names.len()),
}
}