1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// use super::{EnumQueuePlaneDataType, EnumQueuePlaneEnd, EnumQueuePlaneHead, PrimitiveTraits};
use super::PrimitiveTraits;

pub trait OptionTy<T> {
    const __DATA: Option<T>;
    const VALUE: Option<T> = <Self as OptionTy<T>>::__DATA;
}

impl<U: PrimitiveTraits<DATATYPE = Option<T>>, T> OptionTy<T> for U {
    const __DATA: Option<T> = <U as PrimitiveTraits>::__DATA;
}

#[derive(Debug, Copy, Clone)]
pub struct SomeImpl<T: PrimitiveTraits> {
    __phantom: core::marker::PhantomData<T>,
}

impl<T: PrimitiveTraits> PrimitiveTraits for SomeImpl<T> {
    type DATATYPE = Option<T::DATATYPE>;
    const __DATA: Self::DATATYPE = Some(<T as PrimitiveTraits>::__DATA);
}

pub struct NoneImpl;

impl<T> OptionTy<T> for NoneImpl {
    const __DATA: Option<T> = None;
}

// impl<T, U: PrimitiveTraits<DATATYPE = T>> PrimitiveTraits
//     for EnumQueuePlaneHead<Option<T>, EnumQueuePlaneDataType<U, EnumQueuePlaneEnd>, 0>
// {
//     type DATATYPE = Option<T>;
//     const __DATA: Self::DATATYPE = None;
// }

// impl<T, U: PrimitiveTraits<DATATYPE = T>> PrimitiveTraits
//     for EnumQueuePlaneHead<Option<T>, EnumQueuePlaneDataType<U, EnumQueuePlaneEnd>, 1>
// {
//     type DATATYPE = Option<T>;
//     const __DATA: Self::DATATYPE = Some(<U as PrimitiveTraits>::__DATA);
// }

#[macro_export]
macro_rules! Some {
    ($value:ty) => {
        $crate::primitive::SomeImpl<$value>
    };
}

#[macro_export]
macro_rules! None {
    () => {
        $crate::primitive::NoneImpl
    };
}

#[cfg(test)]
mod tests {
    use crate::primitive::{F32Ty, U32Ty, F32, U32};
    use core::mem;

    use super::OptionTy;

    pub const fn tester_inner<T: F32Ty>() -> f32 {
        T::VALUE
    }

    pub const fn tester_inner_u32<T: U32Ty>() -> u32 {
        T::VALUE
    }

    pub const fn tester_inner_option<T: OptionTy<f32>>() -> Option<f32> {
        T::VALUE
    }

    #[test]
    pub fn call_tester() {
        let s: Some!(F32!(-25.333)) = unsafe { mem::zeroed() };
        assert_eq!(core::mem::size_of_val(&s), 0);
        assert_eq!(tester_inner::<F32!(-0.5)>(), -0.5);
        assert_eq!(
            tester_inner_option::<Some!(F32!(-25.333))>(),
            Some(-25.333f32)
        );
        assert_eq!(tester_inner_option::<None!()>(), None);
        assert_eq!(tester_inner_u32::<U32!(0)>(), 0);
    }
}

// type B = const_struct::parse_value!(Option<f32>, None);
// EnumQueuePlaneHead<Option<T>, EnumQueuePlaneDataType<U, EnumQueuePlaneEnd>, 0>
// type B = EnumQueuePlaneHead<
//     Option<f32>,
//     EnumQueuePlaneDataType<
//         F32!({
//             match S {
//                 None => core::mem::zeroed(),
//                 Some(v0) => v0,
//             }
//         }),
//         EnumQueuePlaneEnd,
//     >,
//     {
//         match S {
//             None => 0,
//             Some(_) => 1,
//         }
//     },
// >;