mod id_gen;
mod only;
mod toposort;
pub use id_gen::{IdGenerator, NameGenerator};
use itertools::Itertools;
pub use only::*;
pub use toposort::toposort;
use anyhow::Result;
pub trait OrMap<T> {
fn or_map<F>(self, b: Self, f: F) -> Self
where
F: FnOnce(T, T) -> T;
}
impl<T> OrMap<T> for Option<T> {
fn or_map<F>(self, b: Self, f: F) -> Self
where
F: FnOnce(T, T) -> T,
{
match (self, b) {
(Some(a), Some(b)) => Some(f(a, b)),
(a, None) => a,
(None, b) => b,
}
}
}
pub trait Pluck<T> {
fn pluck<R, F>(&mut self, f: F) -> Vec<R>
where
F: Fn(T) -> Result<R, T>;
}
impl<T> Pluck<T> for Vec<T> {
fn pluck<R, F>(&mut self, f: F) -> Vec<R>
where
F: Fn(T) -> Result<R, T>,
{
let mut matched = Vec::new();
let mut not_matched = Vec::new();
for transform in self.drain(..) {
match f(transform) {
Ok(t) => matched.push(t),
Err(transform) => not_matched.push(transform),
}
}
self.extend(not_matched);
matched
}
}
pub trait BreakUp<T> {
fn break_up<F>(self, f: F) -> (Vec<T>, Vec<T>)
where
F: FnMut(&T) -> bool;
}
impl<T> BreakUp<T> for Vec<T> {
fn break_up<F>(mut self, f: F) -> (Vec<T>, Vec<T>)
where
F: FnMut(&T) -> bool,
{
let position = self.iter().position(f).unwrap_or(self.len());
let after = self.drain(position..).collect_vec();
(self, after)
}
}
pub trait IterOfOptBool {
fn all_true(self) -> Option<bool>;
fn any_true(self) -> Option<bool>;
}
impl<'a, I> IterOfOptBool for I
where
I: Iterator<Item = &'a Option<bool>>,
{
fn all_true(self) -> Option<bool> {
self.cloned()
.fold(Some(true), |a, x| a.zip(x).map(|(a, b)| a && b))
}
fn any_true(self) -> Option<bool> {
self.cloned()
.fold(Some(true), |a, x| a.zip(x).map(|(a, b)| a && b))
}
}