use crate::error::SpaceError;
use crate::region::{RegionPlan, RegionSpec};
use murk_core::{Coord, SpaceInstanceId};
use smallvec::SmallVec;
use std::any::Any;
pub trait Space: Any + Send + Sync + 'static {
fn ndim(&self) -> usize;
fn cell_count(&self) -> usize;
fn neighbours(&self, coord: &Coord) -> SmallVec<[Coord; 8]>;
fn distance(&self, a: &Coord, b: &Coord) -> f64;
fn compile_region(&self, spec: &RegionSpec) -> Result<RegionPlan, SpaceError>;
fn iter_region<'a>(&'a self, plan: &'a RegionPlan) -> Box<dyn Iterator<Item = Coord> + 'a> {
Box::new(plan.coords.iter().cloned())
}
fn map_coord_to_tensor_index(&self, coord: &Coord, plan: &RegionPlan) -> Option<usize> {
plan.coords
.iter()
.position(|c| c == coord)
.map(|i| plan.tensor_indices[i])
}
fn canonical_ordering(&self) -> Vec<Coord>;
fn canonical_rank(&self, coord: &Coord) -> Option<usize> {
self.canonical_ordering().iter().position(|c| c == coord)
}
fn instance_id(&self) -> SpaceInstanceId;
}
impl dyn Space {
pub fn downcast_ref<T: Space>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref::<T>()
}
}