use core::fmt;
use pyo3::prelude::*;
use smallvec::SmallVec;
use crate::ecs::{component_type::PyComponentType, filter::QueryFilter};
#[pyclass(name = "QueryParam", frozen)]
#[derive(Debug, Clone, PartialEq)]
pub struct PyQueryParam {
pub(crate) data: SmallVec<[QueryData; 16]>,
pub(crate) single: bool,
pub(crate) filters: SmallVec<[QueryFilter; 4]>,
pub(crate) single_entity_enforced: bool,
}
impl PyQueryParam {
pub(crate) fn _param_types(&self) -> &[QueryData] {
&self.data
}
}
#[pymethods]
impl PyQueryParam {
#[getter]
pub fn _data_names(&self) -> Vec<String> {
self.data.iter().map(|ct| ct.to_string()).collect()
}
pub fn _data_len(&self) -> usize {
self.data.len()
}
pub fn _filter_len(&self) -> usize {
self.filters.len()
}
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum QueryData {
Entity,
Component {
ty: PyComponentType,
mutable: bool,
optional: bool,
},
}
impl fmt::Display for QueryData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
QueryData::Entity => write!(f, "Entity"),
QueryData::Component {
ty,
mutable,
optional,
} => {
let inner = if *mutable {
format!("Mut[{ty}]")
} else {
format!("{ty}")
};
if *optional {
write!(f, "Optional[{inner}]")
} else {
write!(f, "{inner}")
}
}
}
}
}