use filters::{PyAdded, PyAnyOf, PyChanged, PyHas, PyWith, PyWithout};
use pyo3::{prelude::*, types::PyAny};
use smallvec::{SmallVec, smallvec};
use crate::ecs::{
component_type::PyComponentType, query::query_helpers::extract_component_type_from_query_param,
};
pub mod filters;
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum QueryFilter {
With(PyWith),
Without(PyWithout),
Changed(PyChanged),
Added(PyAdded),
Has(PyHas),
AnyOf(PyAnyOf),
}
pub(crate) fn parse_multi_component_filter(
py: Python,
key: &Bound<'_, PyAny>,
filter_name: &str,
) -> PyResult<SmallVec<[PyComponentType; 4]>> {
if let Ok(args) = key.getattr("__args__") {
let mut components = SmallVec::new();
for item in args.try_iter()? {
let item = item?;
let component = extract_component_type_from_query_param(py, &item)?;
components.push(component);
}
Ok(components)
} else if key.is_instance_of::<pyo3::types::PyTuple>() {
Err(pyo3::exceptions::PyTypeError::new_err(format!(
"Use {}[tuple[...]] for multiple components, not {}[(...)]. \
Example: {}[tuple[ComponentA, ComponentB]]",
filter_name, filter_name, filter_name
)))
} else {
let component = extract_component_type_from_query_param(py, &key)?;
Ok(smallvec![component])
}
}
pub(crate) fn parse_single_component_filter(
py: Python,
key: &Bound<'_, PyAny>,
) -> PyResult<PyComponentType> {
extract_component_type_from_query_param(py, key)
}