poke_engine/
lib.rs

1#[cfg(feature = "gen1")]
2#[path = "gen1/mod.rs"]
3pub mod engine;
4
5#[cfg(feature = "gen2")]
6#[path = "gen2/mod.rs"]
7pub mod engine;
8
9#[cfg(feature = "gen3")]
10#[path = "gen3/mod.rs"]
11pub mod engine;
12
13// All other generations
14#[cfg(not(any(feature = "gen1", feature = "gen2", feature = "gen3")))]
15#[path = "genx/mod.rs"]
16pub mod engine;
17
18pub mod choices;
19pub mod instruction;
20pub mod io;
21pub mod mcts;
22pub mod pokemon;
23pub mod search;
24pub mod state;
25
26#[macro_export]
27macro_rules! assert_unique_feature {
28    () => {};
29    ($first:tt $(,$rest:tt)*) => {
30        $(
31            #[cfg(all(feature = $first, feature = $rest))]
32            compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together"));
33        )*
34        assert_unique_feature!($($rest),*);
35    }
36}
37
38#[macro_export]
39macro_rules! define_enum_with_from_str {
40    // Case when a default variant is provided
41    (
42        #[repr($repr:ident)]
43        $(#[$meta:meta])*
44        $name:ident {
45            $($variant:ident),+ $(,)?
46        },
47        default = $default_variant:ident
48    ) => {
49        #[repr($repr)]
50        $(#[$meta])*
51        pub enum $name {
52            $($variant),+
53        }
54
55        impl std::str::FromStr for $name {
56            type Err = ();
57
58            fn from_str(input: &str) -> Result<Self, Self::Err> {
59                match input.to_uppercase().as_str() {
60                    $(
61                        stringify!($variant) => Ok($name::$variant),
62                    )+
63                    _ => Ok($name::$default_variant),
64                }
65            }
66        }
67
68        impl std::fmt::Display for $name {
69            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
70                write!(f, "{:?}", self)
71            }
72        }
73
74        impl From<$repr> for $name {
75            fn from(value: $repr) -> $name {
76                match value {
77                    $(
78                        x if x == $name::$variant as $repr => $name::$variant,
79                    )+
80                    _ => $name::$default_variant,
81                }
82            }
83        }
84        impl Into<$repr> for $name {
85            fn into(self) -> $repr {
86                self as $repr
87            }
88        }
89    };
90
91    // Case when no default variant is provided
92    (
93        #[repr($repr:ident)]
94        $(#[$meta:meta])*
95        $name:ident {
96            $($variant:ident),+ $(,)?
97        }
98    ) => {
99        #[repr($repr)]
100        $(#[$meta])*
101        pub enum $name {
102            $($variant),+
103        }
104
105        impl std::str::FromStr for $name {
106            type Err = ();
107
108            fn from_str(input: &str) -> Result<Self, Self::Err> {
109                match input.to_uppercase().as_str() {
110                    $(
111                        stringify!($variant) => Ok($name::$variant),
112                    )+
113                    _ => panic!("Invalid {}: {}", stringify!($name), input.to_uppercase().as_str()),
114                }
115            }
116        }
117
118        impl std::fmt::Display for $name {
119            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
120                write!(f, "{:?}", self)
121            }
122        }
123
124        impl From<$repr> for $name {
125            fn from(value: $repr) -> $name {
126                match value {
127                    $(
128                        x if x == $name::$variant as $repr => $name::$variant,
129                    )+
130                    _ => panic!("Invalid {}: {}", stringify!($name), value),
131                }
132            }
133        }
134        impl Into<$repr> for $name {
135            fn into(self) -> $repr {
136                self as $repr
137            }
138        }
139    };
140}
141
142assert_unique_feature!("gen2", "gen3", "gen4", "gen5", "gen6", "gen7", "gen8", "gen9");