diff --git a/crates/types/src/compound/enumerated.rs b/crates/types/src/compound/enumerated.rs index 50c6737..1d8e6a8 100644 --- a/crates/types/src/compound/enumerated.rs +++ b/crates/types/src/compound/enumerated.rs @@ -168,6 +168,13 @@ impl Enum<(), L> { } } +impl Enum { + /// use with care. long term, this probably shouldn't stay public. + pub fn from_components(discr: D, list: L) -> Self { + Self(discr, list) + } +} + pub trait EnumRequirements { type NumVariants: Peano; fn decode_discr(&self) -> Discr; diff --git a/crates/types/src/compound/list/flat.rs b/crates/types/src/compound/list/flat.rs index a9b5fda..9ffede4 100644 --- a/crates/types/src/compound/list/flat.rs +++ b/crates/types/src/compound/list/flat.rs @@ -128,6 +128,10 @@ pub trait IntoList { } pub type List = ::List; +pub type List1 = Node; +pub type List2 = Node>; +pub type List3 = Node>; +pub type List4 = Node>; impl Meta for Node { type Length = P1; diff --git a/crates/types/src/mat/mod.rs b/crates/types/src/mat/mod.rs index 9e4db46..f651488 100644 --- a/crates/types/src/mat/mod.rs +++ b/crates/types/src/mat/mod.rs @@ -1,6 +1,6 @@ use crate::compound::enumerated::{Discr, DiscriminantCodable, Enum, EnumRequirements, InternallyDiscriminated, VariantHandler}; -use crate::compound::list::{IntoList as _, List}; -use crate::compound::peano::{Peano, P2}; +use crate::compound::list::{Indexable, IntoList, List, List2, List3}; +use crate::compound::peano::{Peano, P0, P1, P2, P3}; use crate::real::Real; use crate::vec::Vec3; @@ -27,40 +27,31 @@ pub trait Material: Sized { } } +/// a material which can take on 1 of N types. +/// it's assumed that the first type in the material list is capable of storing the discriminant +/// (i.e. that it implements DiscriminantCodable). #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "fmt", derive(Debug))] -#[derive(Copy, Clone, Default, PartialEq)] -pub struct DiscrMat2(InternallyDiscriminated<(M0, M1)>); +#[derive(Clone, Default, PartialEq)] +pub struct DiscrMat(Enum<(), Mats>); +pub type DiscrMat2 = DiscrMat>; +pub type DiscrMat3 = DiscrMat>; -struct D0(T); -struct D1(T); - -impl DiscrMat2 { - fn new_from_fields(m0: M0, m1: M1) -> Self { - Self(Enum::internally_discriminated((m0, m1))) +impl DiscrMat { + fn new_from_fields(mats: Mats) -> Self { + Self(Enum::from_components((), mats)) } } -impl, M1: Default> DiscrMat2 { - pub fn new0(m: M0) -> Self { - D0(m).into() - } - pub fn new1(m: M1) -> Self { - D1(m).into() - } -} - -impl From> for DiscrMat2 { - fn from(m0: D0) -> Self { - let m0 = m0.0; - Self::new_from_fields(m0, Default::default()) - } -} - -impl, M1> From> for DiscrMat2 { - fn from(m1: D1) -> Self { - let m1 = m1.0; - Self::new_from_fields(M0::encode_discr(Discr::new(1)), m1) +impl DiscrMat { + fn new(m: Mats::Element) -> Self + where + Mats: Indexable

, + Enum<(), Mats>: EnumRequirements, + { + let mut me = Self::default(); + me.0.set::

(m); + me } } @@ -81,7 +72,24 @@ impl> VariantHandler> for MoveBV } } -impl + Material + Copy, M1: Material + Copy> Material for DiscrMat2 +impl Material for DiscrMat2 +where + M0: DiscriminantCodable + Material + Copy, + M1: Material + Copy, +{ + fn conductivity(&self) -> Vec3 { + self.0.dispatch(ConductivityDispatcher) + } + fn move_b_vec(&self, m: Vec3, target_b: Vec3) -> Vec3 { + self.0.dispatch(MoveBVecDispatcher { m, target_b }) + } +} + +impl Material for DiscrMat3 +where + M0: DiscriminantCodable + Material + Copy, + M1: Material + Copy, + M2: Material + Copy, { fn conductivity(&self) -> Vec3 { self.0.dispatch(ConductivityDispatcher) @@ -97,12 +105,12 @@ pub type IsoConductorOr = DiscrMat2, M1>; // IsomorphicConductor itself impl From for IsoConductorOr { fn from(mat: Ferroxcube3R1MH) -> Self { - IsoConductorOr::new1(mat) + IsoConductorOr::new::(mat) } } impl From> for IsoConductorOr { fn from(mat: IsomorphicConductor) -> Self { - IsoConductorOr::new0(mat) + IsoConductorOr::new::(mat) } } @@ -124,10 +132,10 @@ mod test { fn iso_conductor_or_aniso() { type I = IsoConductorOr>; - let c = I::new0(IsomorphicConductor::new(22f32.cast())); + let c = I::new::(IsomorphicConductor::new(22f32.cast())); assert!(c.conductivity() == Vec3::uniform(22.0).cast()); - let c = I::new1(AnisomorphicConductor::new( + let c = I::new::(AnisomorphicConductor::new( Vec3::new(2.0, 3.0, 4.0).cast() ));