1#![allow(clippy::derived_hash_with_manual_eq)]
2use crate::datum::DatumType;
3use crate::dim::TDim;
4use crate::internal::TVec;
5use std::fmt::Debug;
6
7use downcast_rs::{Downcast, impl_downcast};
8use dyn_eq::DynEq;
9use dyn_hash::DynHash;
10
11pub trait ExoticFact:
12 DynHash + dyn_eq::DynEq + Send + Sync + Debug + dyn_clone::DynClone + Downcast
13{
14 fn compatible_with(&self, other: &dyn ExoticFact) -> bool {
18 self.dyn_eq(other)
19 }
20
21 fn clarify_dt_shape(&self) -> Option<(DatumType, TVec<TDim>)> {
22 None
23 }
24
25 fn buffer_sizes(&self) -> TVec<TDim>;
26
27 fn mem_size(&self) -> TDim {
28 self.buffer_sizes().iter().sum::<TDim>()
29 }
30}
31
32impl_downcast!(ExoticFact);
33dyn_hash::hash_trait_object!(ExoticFact);
34dyn_clone::clone_trait_object!(ExoticFact);
35dyn_eq::eq_trait_object!(ExoticFact);
36
37impl<T: ExoticFact> From<T> for Box<dyn ExoticFact> {
38 fn from(v: T) -> Self {
39 Box::new(v)
40 }
41}
42
43impl ExoticFact for TVec<Box<dyn ExoticFact>> {
44 fn buffer_sizes(&self) -> TVec<TDim> {
45 self.iter().flat_map(|it| it.buffer_sizes()).collect()
46 }
47}
48impl ExoticFact for TVec<Option<Box<dyn ExoticFact>>> {
49 fn buffer_sizes(&self) -> TVec<TDim> {
50 self.iter().flatten().flat_map(|it| it.buffer_sizes()).collect()
51 }
52}