clay_core/object/
select.rs

1/// The macro for making a union of objects.
2///
3/// You can read more about the technique [here](https://clay-rs.github.io/knowledge/#objects).
4#[macro_export]
5macro_rules! object_select {
6    ( $Select:ident { $( $Enum:ident ( $Param:ident = $Object:ty ) ),+ $(,)? } ) => {
7        $crate::instance_select!(
8            $Select: $crate::object::Object: $crate::object::ObjectClass {
9                $( $Enum($Param = $Object) ),+
10            }
11        );
12        impl $crate::object::Object for $Select {}
13
14        impl<
15            B_: $crate::shape::Bound,
16            $(
17                $Param: 
18                    $crate::object::Object +
19                    $crate::shape::Bounded<B_>
20            ),+
21        > $crate::shape::Bounded<B_> for $Select<
22            $( $Param ),+
23        > {
24            fn bound(&self) -> Option<B_> {
25                match self {
26                    $( $Select::$Enum(x) => x.bound(), )+
27                }
28            }
29        }
30
31        impl<
32            T_: $crate::shape::Target,
33            $(
34                $Param: 
35                    $crate::object::Object +
36                    $crate::shape::Targeted<T_>
37            ),+
38        > $crate::shape::Targeted<T_> for $Select<
39            $( $Param ),+
40        > {
41            fn target(&self) -> Option<(T_, f64)> {
42                match self {
43                    $( $Select::$Enum(x) => x.target(), )+
44                }
45            }
46        }
47    };
48}
49
50#[cfg(test)]
51mod check {
52    use crate::{
53        shape::test::TestShape,
54        material::test::TestMaterial,
55        object::Covered,
56        object_select,
57    };
58
59    object_select!(
60        TestSelect {
61            Object1(T1 = Covered<TestShape<i32>, TestMaterial<i32>>),
62            Object2(T2 = Covered<TestShape<f32>, TestMaterial<f32>>),
63        }
64    );
65}