1extern crate rayon;
5
6extern crate boow;
7extern crate serde;
8#[macro_use]
9extern crate serde_derive;
10extern crate variant_name;
11
12mod dst;
13mod export;
14mod transform;
15
16pub use dst::*;
17pub use export::*;
18pub use transform::*;
19
20pub use self::variant_name::VariantName;
21
22pub trait DefaultFor: VariantName {
24 fn default_for(variant_name: &str) -> Self;
25}
26
27pub trait EditableVariants: VariantName {
32 fn editable_variants() -> &'static [&'static str];
34 fn editable(variant_name: &str) -> bool {
36 Self::editable_variants().contains(&variant_name)
37 }
38}
39
40#[doc(hidden)]
43#[macro_export]
44macro_rules! cake_fn {
45 ($fn_name: ident<$enum_name: ident, $err_type: ty>() $fn_block: block) => {
47 fn $fn_name(
48 _: Vec<::std::borrow::Cow<$enum_name>>,
49 ) -> Vec<Result<$enum_name, $err_type>> {
50 $fn_block
51 }
52 };
53 ($fn_name: ident<$enum_name: ident, $err_type: ty>($($x: ident: $x_type: ident),*) $fn_block: block) => {
55 fn $fn_name(
56 input: Vec<::std::borrow::Cow<$enum_name>>,
57 ) -> Vec<Result<$enum_name, $err_type>> {
58 #[allow(non_camel_case_types)]
59 enum Args { $($x,)* }
60 if let ($(&$enum_name::$x_type(ref $x), )*) = ($(&*input[Args::$x as usize], )*) {
61 $fn_block
62 } else {
63 panic!("Unexpected argument!")
64 }
65 }
66 };
67}
68
69#[macro_export]
98macro_rules! cake_transform {
99 ($description: expr, $fn_name: ident<$enum_name: ident, $err_type: ty>($($x: ident: $x_type: ident $(= $x_default_val: expr), *),*) -> $($out_type: ident),* $fn_block: block) => {{
100 cake_fn!{$fn_name<$enum_name, $err_type>($($x: $x_type),*) $fn_block}
101 use std::borrow::Cow;
102
103 $crate::Transformation {
104 name: stringify!($fn_name),
105 description: Cow::Borrowed($description),
106 input: vec![$((stringify!($x_type), {
107 cake_some_first_value!($( $enum_name::$x_type($x_default_val) ),*)
108 }), )*],
109 output: vec![$(stringify!($out_type), )*],
110 algorithm: $crate::Algorithm::Function($fn_name),
111 }
112 }};
113}
114
115#[macro_export]
120macro_rules! cake_constant {
121 ($const_name: ident, $($x: expr),*) => {{
122 use std::borrow::Cow;
123 use $crate::VariantName;
124
125 let constant = vec![$($x, )*];
126 $crate::Transformation {
127 name: stringify!($const_name),
128 description: Cow::Borrowed(
129 concat!("Constant variable of type '", stringify!($const_name), "'")
130 ),
131 input: vec![],
132 output: constant.iter().map(|c| c.variant_name()).collect(),
133 algorithm: $crate::Algorithm::Constant(constant),
134 }
135 }};
136}
137
138#[doc(hidden)]
140#[macro_export]
141macro_rules! cake_some_first_value {
142 () => {
143 None
144 };
145 ($x:expr) => {
146 Some($x)
147 };
148 ($x:expr, $($xs:expr)+) => {
149 compile_error!("Only zero or one value is expected.")
150 };
151}