use std::fs::File; use std::io::Write; use std::path::Path; fn main() { let e = std::env::var("OUT_DIR").unwrap(); let mut impl_td = File::create(Path::new(&e).join("impl_td.rs")).unwrap(); let mut impl_rv = File::create(Path::new(&e).join("impl_rv.rs")).unwrap(); let mut impl_pk = File::create(Path::new(&e).join("impl_pk.rs")).unwrap(); for n in 0..26 { let z = ('A'..='Z').take(n).collect::>().into_iter(); generate(z, &mut impl_td, &mut impl_rv, &mut impl_pk); } } fn tup(x: impl Iterator) -> String { let mut s = String::default(); for lem in x { s.push(lem); s.push(','); } s } fn generate( x: impl Iterator + Clone + DoubleEndedIterator + ExactSizeIterator, impl_td: &mut impl Write, impl_rv: &mut impl Write, impl_pk: &mut impl Write, ) { let tupl = tup(x.clone()); let n = x.clone().count(); for i in 0..n.min(10) { let drop = tup(x.clone().skip(i)); let take = tup(x.clone().take(i)); let take_b = tup(x.clone().rev().take(i).rev()); let drop_b = tup(x.clone().rev().skip(i).rev()); write!( impl_td, " impl<{tupl}> TD<{i}> for ({tupl}) {{ type Drop = ({drop}); type Take = ({take}); type TakeB = ({take_b}); type DropB = ({drop_b}); fn dropf(self) -> (Self::Take, Self::Drop) {{ let ({tupl}) = self; (({take}), ({drop})) }} fn dropb(self) -> (Self::DropB, Self::TakeB) {{ let ({tupl}) = self; (({drop_b}), ({take_b})) }} }} ", ) .unwrap(); write!( impl_pk, " impl<{tupl}> Pick<{i}> for ({tupl}) {{ type At = {at}; type L = ({left}); type R = ({right}); type Delete = ({left} /* */ {right}); fn delete(({left}): Self::L, ({right}): Self::R) -> Self::Delete \ {{ ({left} {right}) }} fn repick(({left}): Self::L, at: Self::At, ({right}): Self::R) -> \ Self {{ ({left} at, {right}) }} fn depict(self) -> (Self::L, Self::At, Self::R) {{ let ({tupl}) = self; (({left}), {at}, ({right})) }} }} impl<{tupl} Z> RePick<{i}, Z> for ({tupl}) {{ type New = ({left} Z, {right}); fn unpick(({left}): Self::L, at: Z, ({right}): Self::R) -> \ Self::New {{ ({left} at, {right}) }} }} ", at = x.clone().nth(i).unwrap(), left = tup(x.clone().take(i)), right = tup(x.clone().skip(i + 1)) ) .unwrap(); } let rev = tup(x.clone().rev()); write!( impl_rv, " #[allow(non_snake_case)] impl<{tupl}> Reverse for ({tupl}) {{ type Reversed = ({rev}); fn reverse(self) -> Self::Reversed {{ let ({x}) = self; ({rev}) }} }} ", x = tup(x.clone()), ) .unwrap(); }