#![cfg_attr(rustfmt, rustfmt::skip)] use super::*; type Result = ::core::result::Result; pub(in crate) trait CollectVec : Sized + IntoIterator { fn vec (self: Self) -> Vec { impl CollectVec for I {} self.into_iter().collect() } } pub(in crate) trait VMap : Sized + IntoIterator { fn vmap ( self: Self, f: impl FnMut(Self::Item) -> T, ) -> Vec { self.into_iter().map(f).collect() } fn try_vmap ( self: Self, f: impl FnMut(Self::Item) -> Result ) -> Result, E> { self.into_iter().map(f).collect() } } impl VMap for I where Self : Sized + IntoIterator, {} pub(in crate) trait Extend_ { fn extend_ ( &mut self, iterable: I, ) where Self : Extend, I : IntoIterator, { impl Extend_ for T {} self.extend(iterable) } fn extend_one_ ( &mut self, item: A, ) where Self : Extend, { self.extend([item]) } } pub trait Also : Sized { fn also (mut self, tweak: impl FnOnce(&mut Self)) -> Self { impl Also for T {} tweak(&mut self); self } } /// Allows to convert a `bool` or an `Option` into a `#( … )*`-usable /// interpolable (to mock the `$( … )?` from `macro_rules!` macros). pub trait Kleene<'r> { type Ret; fn kleenable (self: &'r Self) -> Self::Ret ; } impl<'r, T : 'r + ToTokens> Kleene<'r> for Option { type Ret = &'r [T]; fn kleenable (self: &'r Option) -> &'r [T] { self.as_ref().map_or(&[], slice::from_ref) } } // `bool` can be viewed as a `Option`. impl Kleene<'_> for bool { type Ret = &'static [EmptyTs]; fn kleenable (self: &'_ bool) -> &'static [EmptyTs] { if let true = self { &[EmptyTs] } else { &[] } } } pub struct EmptyTs; impl ToTokens for EmptyTs { fn to_tokens (self: &'_ EmptyTs, _: &mut TokenStream2) {} }