use std::collections::HashSet; use std::marker::PhantomData; use crate::component::Component; use crate::EntityComponent; /// Query options. pub trait Options { fn entity_filter<'component>( components: impl IntoIterator, ) -> bool; } impl Options for () { fn entity_filter<'component>( _: impl IntoIterator, ) -> bool { true } } pub struct With where ComponentT: Component, { _pd: PhantomData, } impl Options for With where ComponentT: Component, { fn entity_filter<'component>( components: impl IntoIterator, ) -> bool { let ids_set = components .into_iter() .map(|component| component.id) .collect::>(); ids_set.contains(&ComponentT::id()) } } pub struct Not where OptionsT: Options, { _pd: PhantomData, } impl Options for Not where OptionsT: Options, { fn entity_filter<'component>( components: impl IntoIterator, ) -> bool { !OptionsT::entity_filter(components) } }