1use std::fmt::{Display, Formatter};
4
5use bitflags::bitflags;
6
7use crate::context::ScopeContext;
8use crate::everything::Everything;
9use crate::game::Game;
10use crate::helpers::{camel_case_to_separated_words, display_choices, snake_case_to_camel_case};
11use crate::item::Item;
12use crate::report::{err, ErrorKey};
13use crate::token::Token;
14
15#[cfg(any(feature = "vic3", feature = "ck3"))]
17type ScopesBits = u128;
18#[cfg(not(any(feature = "vic3", feature = "ck3")))]
19type ScopesBits = u64;
20
21bitflags! {
22 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
35 #[rustfmt::skip] pub struct Scopes: ScopesBits {
37 const None = 0x0000_0001;
39 const Value = 0x0000_0002;
40 const Bool = 0x0000_0004;
41 const Flag = 0x0000_0008;
42
43 #[cfg(any(feature = "vic3", feature = "imperator"))]
46 const Color = 0x0000_0010;
47 #[cfg(any(feature = "vic3", feature = "imperator", feature = "hoi4"))]
48 const Country = 0x0000_0020;
49 const Character = 0x0000_0040;
50 #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator"))]
51 const Culture = 0x0000_0080;
52 #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator"))]
53 const Province = 0x0000_0100;
54 #[cfg(any(feature = "vic3", feature = "imperator"))]
55 const Pop = 0x0000_0200;
56 #[cfg(any(feature = "vic3", feature = "imperator"))]
57 const Party = 0x0000_0400;
58 #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator"))]
59 const Religion = 0x0000_0800;
60 #[cfg(any(feature = "vic3", feature = "imperator", feature = "hoi4"))]
61 const State = 0x0000_1000;
62 #[cfg(any(feature = "ck3", feature = "vic3", feature = "imperator"))]
63 const War = 0x0000_2000;
64 #[cfg(any(feature = "vic3", feature = "hoi4"))]
65 const StrategicRegion = 0x0000_4000;
66
67 #[cfg(feature = "ck3")] const Accolade = 0x0001_0000;
69 #[cfg(feature = "ck3")] const AccoladeType = 0x0002_0000;
70 #[cfg(feature = "ck3")] const Activity = 0x0004_0000;
71 #[cfg(feature = "ck3")] const ActivityType = 0x0008_0000;
72 #[cfg(feature = "ck3")] const Army = 0x0010_0000;
73 #[cfg(feature = "ck3")] const Artifact = 0x0020_0000;
74 #[cfg(feature = "ck3")] const CasusBelli = 0x0040_0000;
75 #[cfg(feature = "ck3")] const CharacterMemory = 0x0080_0000;
76 #[cfg(feature = "ck3")] const Combat = 0x0100_0000;
77 #[cfg(feature = "ck3")] const CombatSide = 0x0200_0000;
78 #[cfg(feature = "ck3")] const CouncilTask = 0x0400_0000;
79 #[cfg(feature = "ck3")] const CulturePillar = 0x0800_0000;
80 #[cfg(feature = "ck3")] const CultureTradition = 0x1000_0000;
81 #[cfg(feature = "ck3")] const Decision = 0x2000_0000;
82 #[cfg(feature = "ck3")] const Doctrine = 0x4000_0000;
83 #[cfg(feature = "ck3")] const Dynasty = 0x8000_0000;
84 #[cfg(feature = "ck3")] const DynastyHouse = 0x0000_0001_0000_0000;
85 #[cfg(feature = "ck3")] const Faction = 0x0000_0002_0000_0000;
86 #[cfg(feature = "ck3")] const Faith = 0x0000_0004_0000_0000;
87 #[cfg(feature = "ck3")] const GovernmentType = 0x0000_0008_0000_0000;
88 #[cfg(feature = "ck3")] const GreatHolyWar = 0x0000_0010_0000_0000;
89 #[cfg(feature = "ck3")] const HolyOrder = 0x0000_0020_0000_0000;
90 #[cfg(feature = "ck3")] const Inspiration = 0x0000_0040_0000_0000;
91 #[cfg(feature = "ck3")] const LandedTitle = 0x0000_0080_0000_0000;
92 #[cfg(feature = "ck3")] const MercenaryCompany = 0x0000_0100_0000_0000;
93 #[cfg(feature = "ck3")] const Scheme = 0x0000_0200_0000_0000;
94 #[cfg(feature = "ck3")] const Secret = 0x0000_0400_0000_0000;
95 #[cfg(feature = "ck3")] const StoryCycle = 0x0000_0800_0000_0000;
96 #[cfg(feature = "ck3")] const Struggle = 0x0000_1000_0000_0000;
97 #[cfg(feature = "ck3")] const TitleAndVassalChange = 0x0000_2000_0000_0000;
98 #[cfg(feature = "ck3")] const Trait = 0x0000_4000_0000_0000;
99 #[cfg(feature = "ck3")] const TravelPlan = 0x0000_8000_0000_0000;
100 #[cfg(feature = "ck3")] const VassalContract = 0x0001_0000_0000_0000;
101 #[cfg(feature = "ck3")] const VassalObligationLevel = 0x0002_0000_0000_0000;
102 #[cfg(feature = "ck3")] const HoldingType = 0x0004_0000_0000_0000;
104 #[cfg(feature = "ck3")] const TaxSlot = 0x0008_0000_0000_0000;
105 #[cfg(feature = "ck3")] const EpidemicType = 0x0010_0000_0000_0000;
107 #[cfg(feature = "ck3")] const Epidemic = 0x0020_0000_0000_0000;
108 #[cfg(feature = "ck3")] const LegendType = 0x0040_0000_0000_0000;
109 #[cfg(feature = "ck3")] const Legend = 0x0080_0000_0000_0000;
110 #[cfg(feature = "ck3")] const GeographicalRegion = 0x0100_0000_0000_0000;
111 #[cfg(feature = "ck3")] const Domicile = 0x0200_0000_0000_0000;
113 #[cfg(feature = "ck3")] const AgentSlot = 0x0400_0000_0000_0000;
114 #[cfg(feature = "ck3")] const TaskContract = 0x0800_0000_0000_0000;
115 #[cfg(feature = "ck3")] const TaskContractType = 0x1000_0000_0000_0000;
116 #[cfg(feature = "ck3")] const Regiment = 0x2000_0000_0000_0000;
117 #[cfg(feature = "ck3")] const CasusBelliType = 0x4000_0000_0000_0000;
118 #[cfg(feature = "ck3")] const CourtPosition = 0x8000_0000_0000_0000;
120 #[cfg(feature = "ck3")] const CourtPositionType = 0x0000_0000_0000_0001_0000_0000_0000_0000;
121 #[cfg(feature = "ck3")] const Situation = 0x0000_0000_0000_0002_0000_0000_0000_0000;
123 #[cfg(feature = "ck3")] const SituationParticipantGroup = 0x0000_0000_0000_0004_0000_0000_0000_0000;
124 #[cfg(feature = "ck3")] const SituationSubRegion = 0x0000_0000_0000_0008_0000_0000_0000_0000;
125 #[cfg(feature = "ck3")] const Confederation = 0x0000_0000_0000_0010_0000_0000_0000_0000;
126
127
128 #[cfg(feature = "vic3")] const Battle = 0x0001_0000;
129 #[cfg(feature = "vic3")] const BattleSide = 0x0002_0000;
130 #[cfg(feature = "vic3")] const Building = 0x0004_0000;
131 #[cfg(feature = "vic3")] const BuildingType = 0x0008_0000;
132 #[cfg(feature = "vic3")] const CanalType = 0x0010_0000;
133 #[cfg(feature = "vic3")] const CivilWar = 0x0020_0000;
134 #[cfg(feature = "vic3")] const CulturalCommunity = 0x0040_0000;
135 #[cfg(feature = "vic3")] const NewCombatUnit = 0x0080_0000;
136 #[cfg(feature = "vic3")] const CommanderOrderType = 0x0100_0000;
137 #[cfg(feature = "vic3")] const CountryCreation = 0x0200_0000;
138 #[cfg(feature = "vic3")] const CountryDefinition = 0x0400_0000;
139 #[cfg(feature = "vic3")] const CountryFormation = 0x0800_0000;
140 #[cfg(feature = "vic3")] const Decree = 0x1000_0000;
141 #[cfg(feature = "vic3")] const DiplomaticAction = 0x2000_0000;
142 #[cfg(feature = "vic3")] const DiplomaticPact = 0x4000_0000;
143 #[cfg(feature = "vic3")] const DiplomaticPlay = 0x8000_0000;
144 #[cfg(feature = "vic3")] const DiplomaticRelations = 0x0000_0001_0000_0000;
145 #[cfg(feature = "vic3")] const Front = 0x0000_0002_0000_0000;
146 #[cfg(feature = "vic3")] const Goods = 0x0000_0004_0000_0000;
147 #[cfg(feature = "vic3")] const Hq = 0x0000_0008_0000_0000;
148 #[cfg(feature = "vic3")] const Ideology = 0x0000_0010_0000_0000;
149 #[cfg(feature = "vic3")] const Institution = 0x0000_0020_0000_0000;
150 #[cfg(feature = "vic3")] const InstitutionType = 0x0000_0040_0000_0000;
151 #[cfg(feature = "vic3")] const InterestMarker = 0x0000_0080_0000_0000;
152 #[cfg(feature = "vic3")] const InterestGroup = 0x0000_0100_0000_0000;
153 #[cfg(feature = "vic3")] const InterestGroupTrait = 0x0000_0200_0000_0000;
154 #[cfg(feature = "vic3")] const InterestGroupType = 0x0000_0400_0000_0000;
155 #[cfg(feature = "vic3")] const JournalEntry = 0x0000_0800_0000_0000;
156 #[cfg(feature = "vic3")] const Law = 0x0000_1000_0000_0000;
157 #[cfg(feature = "vic3")] const LawType = 0x0000_2000_0000_0000;
158 #[cfg(feature = "vic3")] const Market = 0x0000_4000_0000_0000;
159 #[cfg(feature = "vic3")] const MarketGoods = 0x0000_8000_0000_0000;
160 #[cfg(feature = "vic3")] const Objective = 0x0001_0000_0000_0000;
161 #[cfg(feature = "vic3")] const PoliticalMovement = 0x0002_0000_0000_0000;
162 #[cfg(feature = "vic3")] const PopType = 0x0004_0000_0000_0000;
163 #[cfg(feature = "vic3")] const ShippingLanes = 0x0008_0000_0000_0000;
164 #[cfg(feature = "vic3")] const StateRegion = 0x0010_0000_0000_0000;
165 #[cfg(feature = "vic3")] const StateTrait = 0x0020_0000_0000_0000;
166 #[cfg(feature = "vic3")] const Technology = 0x0080_0000_0000_0000;
168 #[cfg(feature = "vic3")] const TechnologyStatus = 0x0100_0000_0000_0000;
169 #[cfg(feature = "vic3")] const Theater = 0x0200_0000_0000_0000;
170 #[cfg(feature = "vic3")] const CombatUnitType = 0x1000_0000_0000_0000;
172 #[cfg(feature = "vic3")] const MilitaryFormation = 0x2000_0000_0000_0000;
173 #[cfg(feature = "vic3")] const Sway = 0x4000_0000_0000_0000;
174 #[cfg(feature = "vic3")] const StateGoods = 0x8000_0000_0000_0000;
175 #[cfg(feature = "vic3")] const DiplomaticDemand = 0x0000_0000_0000_0001_0000_0000_0000_0000;
176 #[cfg(feature = "vic3")] const Company = 0x0000_0000_0000_0002_0000_0000_0000_0000;
177 #[cfg(feature = "vic3")] const CompanyType = 0x0000_0000_0000_0004_0000_0000_0000_0000;
178 #[cfg(feature = "vic3")] const TravelNode = 0x0000_0000_0000_0008_0000_0000_0000_0000;
179 #[cfg(feature = "vic3")] const TravelNodeDefinition = 0x0000_0000_0000_0010_0000_0000_0000_0000;
180 #[cfg(feature = "vic3")] const TravelConnection = 0x0000_0000_0000_0020_0000_0000_0000_0000;
181 #[cfg(feature = "vic3")] const TravelConnectionDefinition = 0x0000_0000_0000_0040_0000_0000_0000_0000;
182 #[cfg(feature = "vic3")] const Invasion = 0x0000_0000_0000_0080_0000_0000_0000_0000;
183 #[cfg(feature = "vic3")] const MobilizationOption = 0x0000_0000_0000_0100_0000_0000_0000_0000;
184 #[cfg(feature = "vic3")] const PowerBlocPrincipleGroup = 0x0000_0000_0000_0200_0000_0000_0000_0000;
185 #[cfg(feature = "vic3")] const DiplomaticPlayType = 0x0000_0000_0000_0400_0000_0000_0000_0000;
186 #[cfg(feature = "vic3")] const DiplomaticCatalyst = 0x0000_0000_0000_0800_0000_0000_0000_0000;
187 #[cfg(feature = "vic3")] const DiplomaticCatalystType = 0x0000_0000_0000_1000_0000_0000_0000_0000;
188 #[cfg(feature = "vic3")] const DiplomaticCatalystCategory = 0x0000_0000_0000_2000_0000_0000_0000_0000;
189 #[cfg(feature = "vic3")] const PoliticalLobby = 0x0000_0000_0000_4000_0000_0000_0000_0000;
190 #[cfg(feature = "vic3")] const PoliticalLobbyType = 0x0000_0000_0000_8000_0000_0000_0000_0000;
191 #[cfg(feature = "vic3")] const PoliticalLobbyAppeasement = 0x0000_0000_0001_0000_0000_0000_0000_0000;
192 #[cfg(feature = "vic3")] const PowerBloc = 0x0000_0000_0002_0000_0000_0000_0000_0000;
193 #[cfg(feature = "vic3")] const PowerBlocIdentity = 0x0000_0000_0004_0000_0000_0000_0000_0000;
194 #[cfg(feature = "vic3")] const PowerBlocPrinciple = 0x0000_0000_0008_0000_0000_0000_0000_0000;
195 #[cfg(feature = "vic3")] const HarvestCondition = 0x0000_0000_0010_0000_0000_0000_0000_0000;
196 #[cfg(feature = "vic3")] const PoliticalMovementType = 0x0000_0000_0020_0000_0000_0000_0000_0000;
197 #[cfg(feature = "vic3")] const HarvestConditionType = 0x0000_0000_0040_0000_0000_0000_0000_0000;
198 #[cfg(feature = "vic3")] const TreatyArticle = 0x0000_0000_0080_0000_0000_0000_0000_0000;
199 #[cfg(feature = "vic3")] const TreatyOptions = 0x0000_0000_0100_0000_0000_0000_0000_0000;
200 #[cfg(feature = "vic3")] const TreatyArticleOptions = 0x0000_0000_0200_0000_0000_0000_0000_0000;
201 #[cfg(feature = "vic3")] const Treaty = 0x0000_0000_0400_0000_0000_0000_0000_0000;
202 #[cfg(feature = "vic3")] const BuildingGroup = 0x0000_0000_0800_0000_0000_0000_0000_0000;
203
204 #[cfg(feature = "imperator")] const Area = 0x0001_0000;
205 #[cfg(feature = "imperator")] const CountryCulture = 0x0002_0000;
206 #[cfg(feature = "imperator")] const CultureGroup = 0x0004_0000;
207 #[cfg(feature = "imperator")] const Deity = 0x0008_0000;
208 #[cfg(feature = "imperator")] const Family = 0x0010_0000;
209 #[cfg(feature = "imperator")] const Governorship = 0x0020_0000;
210 #[cfg(feature = "imperator")] const GreatWork = 0x0040_0000;
211 #[cfg(feature = "imperator")] const Job = 0x0080_0000;
212 #[cfg(feature = "imperator")] const Legion = 0x0100_0000;
213 #[cfg(feature = "imperator")] const LevyTemplate = 0x0200_0000;
214 #[cfg(feature = "imperator")] const Region = 0x0400_0000;
215 #[cfg(feature = "imperator")] const Siege = 0x0800_0000;
216 #[cfg(feature = "imperator")] const SubUnit = 0x1000_0000;
217 #[cfg(feature = "imperator")] const Treasure = 0x2000_0000;
218 #[cfg(feature = "imperator")] const Unit = 0x4000_0000;
219
220 #[cfg(feature = "hoi4")] const Ace = 0x0001_0000;
221 #[cfg(feature = "hoi4")] const Combatant = 0x0002_0000;
222 #[cfg(feature = "hoi4")] const Division = 0x0004_0000;
223 #[cfg(feature = "hoi4")] const IndustrialOrg = 0x0008_0000;
224 #[cfg(feature = "hoi4")] const Operation = 0x0010_0000;
225 #[cfg(feature = "hoi4")] const PurchaseContract = 0x0020_0000;
226 #[cfg(feature = "hoi4")] const RaidInstance = 0x0040_0000;
227 #[cfg(feature = "hoi4")] const SpecialProject = 0x0080_0000;
228 #[cfg(feature = "hoi4")] const CombinedCountryAndState = 0x0200_0000;
231 #[cfg(feature = "hoi4")] const CombinedCountryAndCharacter = 0x0400_0000;
232 }
233}
234
235impl Scopes {
238 pub const fn non_primitive() -> Scopes {
239 Scopes::all()
240 .difference(Scopes::None.union(Scopes::Value).union(Scopes::Bool).union(Scopes::Flag))
241 }
242
243 pub const fn primitive() -> Scopes {
244 Scopes::Value.union(Scopes::Bool).union(Scopes::Flag)
245 }
246
247 pub const fn all_but_none() -> Scopes {
248 Scopes::all().difference(Scopes::None)
249 }
250
251 pub fn from_snake_case(s: &str) -> Option<Scopes> {
253 #[cfg(feature = "ck3")]
254 if Game::is_ck3() {
255 match s {
257 "ghw" => return Some(Scopes::GreatHolyWar),
258 "story" => return Some(Scopes::StoryCycle),
259 "great_holy_war" | "story_cycle" => return None,
260 _ => (),
261 }
262 }
263
264 Scopes::from_name(&snake_case_to_camel_case(s))
265 }
266
267 pub fn from_snake_case_multi(s: &str) -> Option<Scopes> {
270 let mut scopes = Scopes::empty();
271 for part in s.split('|') {
272 if let Some(scope) = Scopes::from_snake_case(part) {
273 scopes |= scope;
274 } else {
275 return None;
276 }
277 }
278 if scopes == Scopes::empty() {
281 return None;
282 }
283 Some(scopes)
284 }
285}
286
287impl Display for Scopes {
288 fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
289 if *self == Scopes::all() {
290 write!(f, "any scope")
291 } else if *self == Scopes::primitive() {
292 write!(f, "any primitive scope")
293 } else if *self == Scopes::non_primitive() {
294 write!(f, "non-primitive scope")
295 } else if *self == Scopes::all_but_none() {
296 write!(f, "any except none scope")
297 } else {
298 let mut vec = Vec::new();
299 for (name, _) in self.iter_names() {
300 vec.push(camel_case_to_separated_words(name));
301 }
302 let vec: Vec<&str> = vec.iter().map(String::as_ref).collect();
303 display_choices(f, &vec, "or")
304 }
305 }
306}
307
308#[derive(Copy, Clone, Debug, Eq, PartialEq)]
310pub enum ArgumentValue {
311 #[cfg(any(feature = "ck3", feature = "vic3"))]
313 Scope(Scopes),
314 Item(Item),
316 #[cfg(any(feature = "ck3", feature = "vic3"))]
318 ScopeOrItem(Scopes, Item),
319 #[cfg(feature = "ck3")]
321 TraitTrack,
322 #[cfg(any(feature = "vic3", feature = "imperator"))]
324 Modif,
325 #[cfg(any(feature = "vic3", feature = "ck3"))]
327 Identifier(&'static str),
328 UncheckedValue,
330}
331
332#[allow(unused_variables)] pub fn scope_to_scope(name: &Token, inscopes: Scopes) -> Option<(Scopes, Scopes)> {
343 let scope_to_scope = match Game::game() {
344 #[cfg(feature = "ck3")]
345 Game::Ck3 => crate::ck3::tables::targets::scope_to_scope,
346 #[cfg(feature = "vic3")]
347 Game::Vic3 => crate::vic3::tables::targets::scope_to_scope,
348 #[cfg(feature = "imperator")]
349 Game::Imperator => crate::imperator::tables::targets::scope_to_scope,
350 #[cfg(feature = "hoi4")]
351 Game::Hoi4 => crate::hoi4::tables::targets::scope_to_scope,
352 };
353 let scope_to_scope_removed = match Game::game() {
354 #[cfg(feature = "ck3")]
355 Game::Ck3 => crate::ck3::tables::targets::scope_to_scope_removed,
356 #[cfg(feature = "vic3")]
357 Game::Vic3 => crate::vic3::tables::targets::scope_to_scope_removed,
358 #[cfg(feature = "imperator")]
359 Game::Imperator => crate::imperator::tables::targets::scope_to_scope_removed,
360 #[cfg(feature = "hoi4")]
361 Game::Hoi4 => crate::hoi4::tables::targets::scope_to_scope_removed,
362 };
363
364 let name_lc = name.as_str().to_ascii_lowercase();
365 if let scopes @ Some((from, _)) = scope_to_scope(&name_lc) {
366 #[cfg(feature = "vic3")]
367 if Game::is_vic3() && name_lc == "type" {
368 let mut outscopes = Scopes::empty();
371 if inscopes.contains(Scopes::Building) {
372 outscopes |= Scopes::BuildingType;
373 }
374 if inscopes.contains(Scopes::Company) {
375 outscopes |= Scopes::CompanyType;
376 }
377 if inscopes.contains(Scopes::DiplomaticPlay) {
378 outscopes |= Scopes::DiplomaticPlayType;
379 }
380 if inscopes.contains(Scopes::DiplomaticCatalyst) {
381 outscopes |= Scopes::DiplomaticCatalystType;
382 }
383 if inscopes.contains(Scopes::PoliticalLobby) {
384 outscopes |= Scopes::PoliticalLobbyType;
385 }
386 if inscopes.contains(Scopes::Institution) {
387 outscopes |= Scopes::InstitutionType;
388 }
389 if inscopes.contains(Scopes::InterestGroup) {
390 outscopes |= Scopes::InterestGroupType;
391 }
392 if inscopes.contains(Scopes::Law) {
393 outscopes |= Scopes::LawType;
394 }
395 if inscopes.contains(Scopes::PoliticalMovement) {
396 outscopes |= Scopes::PoliticalMovementType;
397 }
398 if inscopes.contains(Scopes::HarvestCondition) {
399 outscopes |= Scopes::HarvestConditionType;
400 }
401 if !outscopes.is_empty() {
402 return Some((from, outscopes));
403 }
404 }
405 scopes
406 } else if let Some((version, explanation)) = scope_to_scope_removed(&name_lc) {
407 let msg = format!("`{name}` was removed in {version}");
408 err(ErrorKey::Removed).strong().msg(msg).info(explanation).loc(name).push();
409 Some((Scopes::all(), Scopes::all_but_none()))
410 } else {
411 None
412 }
413}
414
415pub fn scope_prefix(prefix: &Token) -> Option<(Scopes, Scopes, ArgumentValue)> {
425 let scope_prefix = match Game::game() {
426 #[cfg(feature = "ck3")]
427 Game::Ck3 => crate::ck3::tables::targets::scope_prefix,
428 #[cfg(feature = "vic3")]
429 Game::Vic3 => crate::vic3::tables::targets::scope_prefix,
430 #[cfg(feature = "imperator")]
431 Game::Imperator => crate::imperator::tables::targets::scope_prefix,
432 #[cfg(feature = "hoi4")]
433 Game::Hoi4 => crate::hoi4::tables::targets::scope_prefix,
434 };
435 let prefix_lc = prefix.as_str().to_ascii_lowercase();
436 scope_prefix(&prefix_lc)
437}
438
439pub fn needs_prefix(arg: &str, data: &Everything, scopes: Scopes) -> Option<&'static str> {
447 match Game::game() {
448 #[cfg(feature = "ck3")]
449 Game::Ck3 => crate::ck3::scopes::needs_prefix(arg, data, scopes),
450 #[cfg(feature = "vic3")]
451 Game::Vic3 => crate::vic3::scopes::needs_prefix(arg, data, scopes),
452 #[cfg(feature = "imperator")]
453 Game::Imperator => crate::imperator::scopes::needs_prefix(arg, data, scopes),
454 #[cfg(feature = "hoi4")]
455 Game::Hoi4 => crate::hoi4::scopes::needs_prefix(arg, data, scopes),
456 }
457}
458
459pub fn scope_iterator(
469 name: &Token,
470 data: &Everything,
471 sc: &mut ScopeContext,
472) -> Option<(Scopes, Scopes)> {
473 let scope_iterator = match Game::game() {
474 #[cfg(feature = "ck3")]
475 Game::Ck3 => crate::ck3::tables::iterators::iterator,
476 #[cfg(feature = "vic3")]
477 Game::Vic3 => crate::vic3::tables::iterators::iterator,
478 #[cfg(feature = "imperator")]
479 Game::Imperator => crate::imperator::tables::iterators::iterator,
480 #[cfg(feature = "hoi4")]
481 Game::Hoi4 => crate::hoi4::tables::iterators::iterator,
482 };
483 let scope_iterator_removed = match Game::game() {
484 #[cfg(feature = "ck3")]
485 Game::Ck3 => crate::ck3::tables::iterators::iterator_removed,
486 #[cfg(feature = "vic3")]
487 Game::Vic3 => crate::vic3::tables::iterators::iterator_removed,
488 #[cfg(feature = "imperator")]
489 Game::Imperator => crate::imperator::tables::iterators::iterator_removed,
490 #[cfg(feature = "hoi4")]
491 Game::Hoi4 => crate::hoi4::tables::iterators::iterator_removed,
492 };
493
494 let name_lc = name.as_str().to_ascii_lowercase();
495 if let scopes @ Some(_) = scope_iterator(&name_lc) {
496 return scopes;
497 }
498 if let Some((version, explanation)) = scope_iterator_removed(&name_lc) {
499 let msg = format!("`{name}` iterators were removed in {version}");
500 err(ErrorKey::Removed).strong().msg(msg).info(explanation).loc(name).push();
501 return Some((Scopes::all(), Scopes::all()));
502 }
503 #[cfg(feature = "jomini")]
504 if Game::is_jomini() && data.scripted_lists.exists(name.as_str()) {
505 data.scripted_lists.validate_call(name, data, sc);
506 return data
507 .scripted_lists
508 .base(name)
509 .and_then(|base| scope_iterator(&base.as_str().to_ascii_lowercase()));
510 }
511 #[cfg(feature = "hoi4")]
512 let _ = &data; #[cfg(feature = "hoi4")]
514 let _ = ≻ None
516}