1#![deny(missing_docs)]
2
3use frunk::labelled::Transmogrifier;
11use frunk::{HCons, HNil};
12use std::marker::PhantomData;
13
14pub enum HEither<H, T> {
24 Head(H),
26 Tail(T),
28}
29
30pub struct Variant<K, T> {
33 pub key: &'static str,
35 pub value: T,
37 pub name_type_holder: PhantomData<K>,
39}
40
41#[macro_export]
43macro_rules! variant {
44 (($($repeated: ty),*), $value: expr) => {
46 $crate::variant!( ($($repeated),*), $value, concat!( $(stringify!($repeated)),* ) )
47 };
48 (($($repeated: ty,)*), $value: expr) => {
50 $crate::variant!( ($($repeated),*), $value )
51 };
52 ($name_type: ty, $value: expr) => {
54 $crate::variant!( $name_type, $value, stringify!($name_type) )
55 };
56 ($name_type: ty, $value: expr, $name: expr) => {
58 $crate::Variant::<$name_type,_> {
59 key: $name,
60 value: $value,
61 name_type_holder: std::marker::PhantomData,
62 }
63 }
64}
65
66impl<TargetHead, TargetTail, SourceHead, SourceTail, HeadIndices, TailIndices, Key>
67 Transmogrifier<HEither<Variant<Key, TargetHead>, TargetTail>, HCons<HeadIndices, TailIndices>>
68 for HEither<Variant<Key, SourceHead>, SourceTail>
69where
70 SourceHead: Transmogrifier<TargetHead, HeadIndices>,
71 SourceTail: Transmogrifier<TargetTail, TailIndices>,
72{
73 #[inline(always)]
74 fn transmogrify(self) -> HEither<Variant<Key, TargetHead>, TargetTail> {
75 match self {
76 HEither::Head(Variant {
77 value: h, key: k, ..
78 }) => HEither::Head(variant!(Key, h.transmogrify(), k)),
79 HEither::Tail(t) => HEither::Tail(t.transmogrify()),
80 }
81 }
82}
83
84pub enum Void {}
86
87impl Transmogrifier<Void, HNil> for Void {
88 fn transmogrify(self) -> Void {
89 match self {}
90 }
91}