use std::iter::Filter;
use std::slice;
use crate::errors::*;
use crate::pod::{Pod, PodType};
use crate::project::{PodOrService, Pods, Project};
#[derive(Debug)]
pub enum ActOn {
All,
AllExceptTasks,
Named(Vec<String>),
}
impl ActOn {
pub fn pods_or_services<'a>(&'a self, project: &'a Project) -> PodsOrServices<'a> {
let state = match self {
ActOn::All => State::PodIter(project.pods()),
ActOn::AllExceptTasks => {
let iter =
project.pods().filter(all_except_tasks as fn(&&Pod) -> bool);
State::FilteredPodIter(iter)
}
ActOn::Named(names) => State::NameIter(names.iter()),
};
PodsOrServices { project, state }
}
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn all_except_tasks(pod: &&Pod) -> bool {
pod.pod_type() != PodType::Task
}
#[derive(Debug)]
#[allow(clippy::enum_variant_names)]
enum State<'a> {
PodIter(Pods<'a>),
FilteredPodIter(Filter<Pods<'a>, fn(&&Pod) -> bool>),
NameIter(slice::Iter<'a, String>),
}
#[derive(Debug)]
pub struct PodsOrServices<'a> {
project: &'a Project,
state: State<'a>,
}
impl<'a> Iterator for PodsOrServices<'a> {
type Item = Result<PodOrService<'a>>;
fn next(&mut self) -> Option<Self::Item> {
match self.state {
State::PodIter(ref mut iter) => {
iter.next().map(|pod| Ok(PodOrService::Pod(pod)))
}
State::FilteredPodIter(ref mut iter) => {
iter.next().map(|pod| Ok(PodOrService::Pod(pod)))
}
State::NameIter(ref mut iter) => {
if let Some(name) = iter.next() {
Some(self.project.pod_or_service_or_err(name))
} else {
None
}
}
}
}
}