tokenize_dir 0.1.0

Tokenize file names in directories to access files in a composable way.
Documentation
use core::iter::{once, empty};

pub trait ToConstraints {
    fn to_constraints(&self) -> impl Iterator<Item = &[usize]>;
}

impl ToConstraints for &[usize] {
    fn to_constraints(&self) -> impl Iterator<Item = &[usize]> {
        once(*self)
    }
}

impl<T: ToConstraints> ToConstraints for &[T]
{
    fn to_constraints(&self) -> impl Iterator<Item = &[usize]> {
        self.iter().flat_map(|x| x.to_constraints())
    }
}

impl<T: ToConstraints, const N: usize> ToConstraints for [T; N]
{
    fn to_constraints(&self) -> impl Iterator<Item = &[usize]> {
        self.iter().flat_map(|x| x.to_constraints())
    }
}

impl<T: ToConstraints, const N: usize> ToConstraints for &[T; N]
{
    fn to_constraints(&self) -> impl Iterator<Item = &[usize]> {
        self.iter().flat_map(|x| x.to_constraints())
    }
}

macro_rules! impl_to_contraints {
    ($($t:ident),* ; $($i:tt),*) => {
        impl<$($t: ToConstraints),*> ToConstraints for ($($t,)*) {
            fn to_constraints(&self) -> impl Iterator<Item = &[usize]> {
                empty()$(.chain(self.$i.to_constraints()))*
            }
        }
    };
}

impl_to_contraints!(;);
impl_to_contraints!(A ; 0);
impl_to_contraints!(A, B ; 0, 1);
impl_to_contraints!(A, B, C ; 0, 1, 2);
impl_to_contraints!(A, B, C, D ; 0, 1, 2, 3);
impl_to_contraints!(A, B, C, D, E ; 0, 1, 2, 3, 4);
impl_to_contraints!(A, B, C, D, E, F ; 0, 1, 2, 3, 4, 5);
impl_to_contraints!(A, B, C, D, E, F, G ; 0, 1, 2, 3, 4, 5, 6);
impl_to_contraints!(A, B, C, D, E, F, G, H ; 0, 1, 2, 3, 4, 5, 6, 7);
impl_to_contraints!(A, B, C, D, E, F, G, H, I ; 0, 1, 2, 3, 4, 5, 6, 7, 8);
impl_to_contraints!(A, B, C, D, E, F, G, H, I, J ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
impl_to_contraints!(A, B, C, D, E, F, G, H, I, J, K ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
impl_to_contraints!(A, B, C, D, E, F, G, H, I, J, K, L ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);