use crate::execution::{
commander::Commander,
progress::{Outcome, Progress, ProgressTracker as _, RichOutcome},
repository::Execution,
};
use crate::job::Job;
use std::sync::{
mpsc::{channel, Receiver},
Arc,
};
#[derive(Debug)]
pub(crate) struct State {
pub job: Arc<Job>,
pub commander: Arc<dyn Commander + Send + Sync>,
pub history: Vec<(Outcome, Receiver<Progress>, Vec<Progress>)>,
}
impl Default for State {
fn default() -> Self {
Self {
job: Default::default(),
commander: Arc::new(()),
history: vec![],
}
}
}
impl State {
pub fn new(job: Arc<Job>) -> Self {
Self {
job,
..Default::default()
}
}
pub fn execute(&mut self) -> Execution {
let (sender, receiver) = channel();
let outcome = Outcome::default();
let outcome2 = outcome.clone();
let tracker = RichOutcome::new(self.job.id.clone(), outcome, sender);
self.history.push((outcome2, receiver, vec![]));
Execution::new(self.job.clone(), self.commander.clone(), Arc::new(tracker))
}
pub fn interpret_with(mut self, commander: Arc<dyn Commander + Send + Sync>) -> State {
self.commander = commander;
self
}
pub fn get_status(&self) -> Option<usize> {
self.history.last().and_then(|(o, _, _)| o.get_status())
}
pub fn is_running(&self) -> bool {
!self.history.is_empty() && self.get_status().is_none()
}
}