use alloc::vec::Vec;
pub struct Val;
impl Val {
pub fn first<T>(results: Vec<Option<T>>) -> Option<T> {
for x in results {
if x.is_some() {
return x;
}
}
None
}
pub fn first_res<T, E>(results: Vec<Result<Option<T>, E>>) -> Result<Option<T>, E> {
for x in results {
match x {
Ok(Some(x)) => return Ok(Some(x)),
Ok(None) => {}
Err(e) => return Err(e),
}
}
Ok(None)
}
pub fn first_opt<T>(results: Vec<Option<Option<T>>>) -> Option<Option<T>> {
for x in results {
match x {
Some(Some(x)) => return Some(Some(x)),
Some(None) => {}
None => return None,
}
}
Some(None)
}
pub fn reduce<T, F>(results: Vec<Option<T>>, mut f: F) -> Option<T>
where
F: FnMut(T, T) -> T,
{
let mut acc = None;
for x in results {
match (acc.is_some(), x) {
(true, Some(x)) => acc = acc.map(|y| f(y, x)),
(false, Some(x)) => acc = Some(x),
(_, None) => {}
}
}
acc
}
pub fn reduce_res<T, E, F>(results: Vec<Result<Option<T>, E>>, mut f: F) -> Result<Option<T>, E>
where
F: FnMut(T, T) -> T,
{
let mut acc = None;
for x in results {
match (acc.is_some(), x) {
(true, Ok(Some(x))) => acc = acc.map(|y| f(y, x)),
(false, Ok(Some(x))) => acc = Some(x),
(_, Ok(None)) => {}
(_, Err(e)) => return Err(e),
}
}
Ok(acc)
}
pub fn reduce_opt<T, F>(results: Vec<Option<Option<T>>>, mut f: F) -> Option<Option<T>>
where
F: FnMut(T, T) -> T,
{
let mut acc = None;
for x in results {
match (acc.is_some(), x) {
(true, Some(Some(x))) => acc = acc.map(|y| f(y, x)),
(false, Some(Some(x))) => acc = Some(x),
(_, Some(None)) => {}
(_, None) => return None,
}
}
Some(acc)
}
}