1use std::sync::OnceLock;
4
5static GAME: OnceLock<Game> = OnceLock::new();
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum Game {
13 #[cfg(feature = "ck3")]
14 Ck3,
15 #[cfg(feature = "vic3")]
16 Vic3,
17 #[cfg(feature = "imperator")]
18 Imperator,
19 #[cfg(feature = "eu5")]
20 Eu5,
21 #[cfg(feature = "hoi4")]
22 Hoi4,
23}
24
25impl Game {
26 pub fn set(game: Game) -> Result<(), String> {
29 GAME.set(game).map_err(|_| "tried to set game type twice".to_string())?;
30 Ok(())
31 }
32
33 #[allow(clippy::self_named_constructors)] #[allow(unreachable_code)]
39 pub fn game() -> Game {
40 #[cfg(all(
41 feature = "ck3",
42 not(feature = "vic3"),
43 not(feature = "imperator"),
44 not(feature = "eu5"),
45 not(feature = "hoi4")
46 ))]
47 return Game::Ck3;
48 #[cfg(all(
49 feature = "vic3",
50 not(feature = "ck3"),
51 not(feature = "imperator"),
52 not(feature = "eu5"),
53 not(feature = "hoi4")
54 ))]
55 return Game::Vic3;
56 #[cfg(all(
57 feature = "imperator",
58 not(feature = "ck3"),
59 not(feature = "vic3"),
60 not(feature = "eu5"),
61 not(feature = "hoi4")
62 ))]
63 return Game::Imperator;
64 #[cfg(all(
65 feature = "hoi4",
66 not(feature = "ck3"),
67 not(feature = "vic3"),
68 not(feature = "imperator"),
69 not(feature = "eu5"),
70 ))]
71 return Game::Hoi4;
72 #[cfg(all(
73 feature = "eu5",
74 not(feature = "ck3"),
75 not(feature = "vic3"),
76 not(feature = "imperator"),
77 not(feature = "hoi4"),
78 ))]
79 return Game::Eu5;
80 *GAME.get().expect("internal error: don't know which game we are validating")
81 }
82
83 #[inline]
85 pub fn is_ck3() -> bool {
86 #[cfg(not(feature = "ck3"))]
87 return false;
88 #[cfg(all(
89 feature = "ck3",
90 not(feature = "vic3"),
91 not(feature = "imperator"),
92 not(feature = "eu5"),
93 not(feature = "hoi4")
94 ))]
95 return true;
96 #[cfg(all(
97 feature = "ck3",
98 any(feature = "vic3", feature = "imperator", feature = "eu5", feature = "hoi4")
99 ))]
100 return GAME.get() == Some(&Game::Ck3);
101 }
102
103 #[inline]
105 pub fn is_vic3() -> bool {
106 #[cfg(not(feature = "vic3"))]
107 return false;
108 #[cfg(all(
109 feature = "vic3",
110 not(feature = "ck3"),
111 not(feature = "imperator"),
112 not(feature = "eu5"),
113 not(feature = "hoi4")
114 ))]
115 return true;
116 #[cfg(all(
117 feature = "vic3",
118 any(feature = "ck3", feature = "imperator", feature = "eu5", feature = "hoi4")
119 ))]
120 return GAME.get() == Some(&Game::Vic3);
121 }
122
123 #[inline]
125 pub fn is_imperator() -> bool {
126 #[cfg(not(feature = "imperator"))]
127 return false;
128 #[cfg(all(
129 feature = "imperator",
130 not(feature = "ck3"),
131 not(feature = "vic3"),
132 not(feature = "eu5"),
133 not(feature = "hoi4")
134 ))]
135 return true;
136 #[cfg(all(
137 feature = "imperator",
138 any(feature = "ck3", feature = "vic3", feature = "hoi4", feature = "eu5")
139 ))]
140 return GAME.get() == Some(&Game::Imperator);
141 }
142
143 #[inline]
145 pub fn is_eu5() -> bool {
146 #[cfg(not(feature = "eu5"))]
147 return false;
148 #[cfg(all(
149 feature = "eu5",
150 not(feature = "ck3"),
151 not(feature = "vic3"),
152 not(feature = "imperator"),
153 not(feature = "hoi4")
154 ))]
155 return true;
156 #[cfg(all(
157 feature = "eu5",
158 any(feature = "ck3", feature = "vic3", feature = "hoi4", feature = "imperator")
159 ))]
160 return GAME.get() == Some(&Game::Eu5);
161 }
162
163 #[inline]
166 pub fn is_jomini() -> bool {
167 Game::is_ck3() || Game::is_vic3() || Game::is_imperator() || Game::is_eu5()
168 }
169
170 #[inline]
172 pub fn is_hoi4() -> bool {
173 #[cfg(not(feature = "hoi4"))]
174 return false;
175 #[cfg(all(
176 feature = "hoi4",
177 not(feature = "ck3"),
178 not(feature = "vic3"),
179 not(feature = "imperator"),
180 not(feature = "eu5")
181 ))]
182 return true;
183 #[cfg(all(
184 feature = "hoi4",
185 any(feature = "ck3", feature = "vic3", feature = "imperator", feature = "eu5")
186 ))]
187 return GAME.get() == Some(&Game::Hoi4);
188 }
189}