use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type Path<T> = Vec<(Part<crate::Spanned<T>>, Opt)>;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub enum Part<I> {
Index(I),
Range(Option<I>, Option<I>),
}
impl<I> Default for Part<I> {
fn default() -> Self {
Self::Range(None, None)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug)]
pub enum Opt {
Optional,
Essential,
}
impl<I> Part<I> {
pub fn map<J>(self, mut f: impl FnMut(I) -> J) -> Part<J> {
match self {
Self::Index(i) => Part::Index(f(i)),
Self::Range(l, h) => Part::Range(l.map(&mut f), h.map(f)),
}
}
}
impl Opt {
pub fn fail<T, E>(self, x: T, f: impl FnOnce(T) -> E) -> Result<T, E> {
match self {
Self::Optional => Ok(x),
Self::Essential => Err(f(x)),
}
}
pub fn collect<T, E>(self, iter: impl Iterator<Item = Result<T, E>>) -> Result<Vec<T>, E> {
match self {
Self::Optional => Ok(iter.filter_map(|x| x.ok()).collect()),
Self::Essential => iter.collect(),
}
}
}