1use std::sync::LazyLock;
2
3use crate::everything::Everything;
4use crate::helpers::TigerHashMap;
5use crate::item::Item;
6use crate::lowercase::Lowercase;
7use crate::report::{ErrorKey, err};
8use crate::scopes::Scopes;
9use crate::token::Token;
10
11const GEOGRAPHIC_REGION_ITERATORS: &[(Scopes, &str, Scopes)] = &[
12 (Scopes::None, "country_in_", Scopes::Country),
13 (Scopes::None, "province_in_", Scopes::Province),
14 (Scopes::None, "state_in_", Scopes::State),
15 (Scopes::None, "state_region_in_", Scopes::StateRegion),
16 (Scopes::None, "strategic_region_in_", Scopes::StrategicRegion),
17];
18
19#[inline]
20pub fn iterator(name_lc: &Lowercase, name: &Token, data: &Everything) -> Option<(Scopes, Scopes)> {
21 for (inscope, pfx, outscope) in GEOGRAPHIC_REGION_ITERATORS.iter().copied() {
22 if let Some(part) = name_lc.strip_prefix_unchecked(pfx) {
23 if !data.item_exists(Item::GeographicRegionShortKey, part.as_str()) {
24 let msg = format!("could not find geographic region short key {part}");
25 let info = format!("so the iterator {name} does not exist");
26 err(ErrorKey::MissingItem).strong().msg(msg).info(info).loc(name).push();
27 }
28 return Some((inscope, outscope));
29 }
30 }
31
32 ITERATOR_MAP.get(name_lc.as_str()).copied()
33}
34
35static ITERATOR_MAP: LazyLock<TigerHashMap<&'static str, (Scopes, Scopes)>> = LazyLock::new(|| {
36 let mut hash = TigerHashMap::default();
37 for (from, s, to) in ITERATOR.iter().copied() {
38 hash.insert(s, (from, to));
39 }
40 hash
41});
42
43const ITERATOR: &[(Scopes, &str, Scopes)] = &[
48 (Scopes::Country, "active_law", Scopes::Law),
49 (Scopes::Country, "active_party", Scopes::Party),
50 (Scopes::None, "character", Scopes::Character),
51 (Scopes::None, "character_in_exile_pool", Scopes::Character),
52 (Scopes::None, "character_in_void", Scopes::Character),
53 (Scopes::Character, "character_role", Scopes::CharacterRole),
54 (Scopes::Country, "civil_war", Scopes::CivilWar),
55 (Scopes::Country, "cobelligerent_in_diplo_play", Scopes::Country),
56 (Scopes::Country, "cobelligerent_in_war", Scopes::Country),
57 (
58 Scopes::Battle
59 .union(Scopes::Building)
60 .union(Scopes::Front)
61 .union(Scopes::Hq)
62 .union(Scopes::MilitaryFormation),
63 "combat_unit",
64 Scopes::NewCombatUnit,
65 ),
66 (Scopes::Country, "company", Scopes::Company),
67 (Scopes::None, "country", Scopes::Country),
68 (Scopes::Country, "country_strategic_region", Scopes::StrategicRegion),
69 (Scopes::None, "decentralized_country", Scopes::Country),
70 (Scopes::Country, "diplomatic_catalyst", Scopes::DiplomaticCatalyst),
71 (Scopes::None, "diplomatic_play", Scopes::DiplomaticPlay),
72 (Scopes::Country, "diplomatically_relevant_country", Scopes::Country),
73 (Scopes::Country, "direct_subject", Scopes::Country),
74 (Scopes::Country, "enemy_in_diplo_play", Scopes::Country),
75 (Scopes::Country, "enemy_in_war", Scopes::Country),
76 (
77 Scopes::Country
78 .union(Scopes::State)
79 .union(Scopes::StateRegion)
80 .union(Scopes::StrategicRegion),
81 "harvest_condition",
82 Scopes::HarvestConditionType,
83 ),
84 (Scopes::None, "in_global_list", Scopes::all_but_none()),
85 (Scopes::Country, "in_hierarchy", Scopes::Country),
86 (Scopes::None, "in_list", Scopes::all_but_none()),
87 (Scopes::None, "in_local_list", Scopes::all_but_none()),
88 (Scopes::PoliticalMovement, "influenced_interest_group", Scopes::InterestGroup),
89 (Scopes::Country, "interest_group", Scopes::InterestGroup),
90 (Scopes::Country, "law", Scopes::Law),
91 (Scopes::PoliticalLobby, "lobby_member", Scopes::InterestGroup),
92 (Scopes::None, "market", Scopes::Market),
93 (Scopes::Market, "market_goods", Scopes::MarketGoods),
94 (Scopes::Party, "member", Scopes::InterestGroup),
95 (
96 Scopes::Country.union(Scopes::Front).union(Scopes::Hq),
97 "military_formation",
98 Scopes::MilitaryFormation,
99 ),
100 (
101 Scopes::Country
102 .union(Scopes::State)
103 .union(Scopes::StateRegion)
104 .union(Scopes::StrategicRegion),
105 "neighbouring_state",
106 Scopes::State,
107 ),
108 (Scopes::Country, "overlord_or_above", Scopes::Country),
109 (Scopes::Company, "owned_country", Scopes::Country),
110 (Scopes::DiplomaticPact, "participant", Scopes::Country),
111 (Scopes::Country.union(Scopes::InterestGroup), "political_lobby", Scopes::PoliticalLobby),
112 (Scopes::Country, "political_movement", Scopes::PoliticalMovement),
113 (Scopes::Law, "possible_amendment_type", Scopes::AmendmentType),
114 (Scopes::Country, "potential_party", Scopes::Party),
115 (Scopes::None, "power_bloc", Scopes::PowerBloc),
116 (Scopes::PowerBloc, "power_bloc_member", Scopes::Country),
117 (Scopes::InterestGroup, "preferred_law", Scopes::Law),
118 (Scopes::Country.union(Scopes::CountryDefinition), "primary_culture", Scopes::Culture),
119 (Scopes::State, "province", Scopes::Province),
121 (Scopes::Country, "rival_country", Scopes::Country),
122 (Scopes::Country, "rivaling_country", Scopes::Country),
123 (
125 Scopes::Country
126 .union(Scopes::Front)
127 .union(Scopes::InterestGroup)
128 .union(Scopes::MilitaryFormation),
129 "scope_admiral",
130 Scopes::Character,
131 ),
132 (Scopes::Country, "scope_ally", Scopes::Country),
133 (Scopes::Law, "scope_amendment", Scopes::Amendment),
134 (
135 Scopes::Country.union(Scopes::Front).union(Scopes::Hq),
136 "scope_army",
137 Scopes::MilitaryFormation,
138 ),
139 (Scopes::Treaty, "scope_article", Scopes::TreatyArticle),
140 (
141 Scopes::TreatyOptions.union(Scopes::Treaty),
142 "scope_article_option",
143 Scopes::TreatyArticleOptions,
144 ),
145 (Scopes::Country.union(Scopes::State), "scope_building", Scopes::Building),
146 (
147 Scopes::Country
148 .union(Scopes::Front)
149 .union(Scopes::InterestGroup)
150 .union(Scopes::MilitaryFormation),
151 "scope_character",
152 Scopes::Character,
153 ),
154 (
155 Scopes::Market.union(Scopes::StateRegion).union(Scopes::StrategicRegion),
156 "scope_country",
157 Scopes::Country,
158 ),
159 (Scopes::Country.union(Scopes::State), "scope_culture", Scopes::Culture),
160 (Scopes::Country, "scope_diplomatic_pact", Scopes::DiplomaticPact),
161 (Scopes::Country.union(Scopes::Hq), "scope_fleet", Scopes::MilitaryFormation),
162 (Scopes::War, "scope_front", Scopes::Front),
163 (
164 Scopes::Country
165 .union(Scopes::Front)
166 .union(Scopes::InterestGroup)
167 .union(Scopes::MilitaryFormation),
168 "scope_general",
169 Scopes::Character,
170 ),
171 (Scopes::Country, "scope_held_interest_marker", Scopes::InterestMarker),
172 (Scopes::Country.union(Scopes::Culture), "scope_homeland_state", Scopes::State),
173 (Scopes::DiplomaticPlay, "scope_initiator_ally", Scopes::Country),
174 (
175 Scopes::Country.union(Scopes::StateRegion).union(Scopes::StrategicRegion),
176 "scope_interest_marker",
177 Scopes::InterestMarker,
178 ),
179 (Scopes::JournalEntry, "scope_je_involved", Scopes::Country),
180 (Scopes::DiplomaticPlay, "scope_play_involved", Scopes::Country),
181 (
182 Scopes::Country
183 .union(Scopes::Front)
184 .union(Scopes::InterestGroup)
185 .union(Scopes::MilitaryFormation),
186 "scope_politician",
187 Scopes::Character,
188 ),
189 (
190 Scopes::Country.union(Scopes::Culture).union(Scopes::InterestGroup).union(Scopes::State),
191 "scope_pop",
192 Scopes::Pop,
193 ),
194 (Scopes::Company, "scope_regional_hqs", Scopes::Building),
195 (Scopes::Country.union(Scopes::MilitaryFormation), "scope_ship", Scopes::Ship),
196 (
197 Scopes::Country
198 .union(Scopes::Front)
199 .union(Scopes::StateRegion)
200 .union(Scopes::StrategicRegion)
201 .union(Scopes::Theater),
202 "scope_state",
203 Scopes::State,
204 ),
205 (Scopes::Country.union(Scopes::State), "scope_strait", Scopes::Strait),
206 (Scopes::DiplomaticPlay, "scope_target_ally", Scopes::Country),
207 (Scopes::Country, "scope_theater", Scopes::Theater),
208 (Scopes::Country, "scope_treaty", Scopes::Treaty),
209 (Scopes::Country, "scope_violate_sovereignty_interested_parties", Scopes::Country),
210 (Scopes::Country, "scope_violate_sovereignty_wars", Scopes::War),
211 (Scopes::Country, "scope_war", Scopes::War),
212 (Scopes::State, "sea_node_adjacent_state", Scopes::State),
214 (Scopes::None, "state", Scopes::State),
215 (Scopes::None, "state_region", Scopes::StateRegion),
216 (Scopes::Country, "strategic_objective", Scopes::State),
217 (Scopes::None, "strategic_region", Scopes::StrategicRegion),
218 (Scopes::Country, "subject_of_subject", Scopes::Country),
219 (Scopes::Country, "subject_or_below", Scopes::Country),
220 (Scopes::PoliticalMovement, "supporting_character", Scopes::Character),
221 (Scopes::None, "treaty", Scopes::Treaty),
222 (Scopes::Country, "valid_mass_migration_culture", Scopes::Culture),
223 (Scopes::War, "war_participant", Scopes::Country),
224];
225
226pub fn iterator_removed(name: &str) -> Option<(&'static str, &'static str)> {
227 for (removed_name, version, explanation) in ITERATOR_REMOVED.iter().copied() {
228 if name == removed_name {
229 return Some((version, explanation));
230 }
231 }
232 None
233}
234
235const ITERATOR_REMOVED: &[(&str, &str, &str)] = &[
236 (
237 "scope_cobelligerent",
238 "1.4.0",
239 "replaced with _cobelligerent_in_diplo_play, _cobelligerent_in_war",
240 ),
241 ("supporting_interest_group", "1.8", "replaced with `_influenced_interest_group`"),
242 ("trade_route", "1.9", "replaced by world market system"),
243];