1use crate::date::Date;
4use crate::macros::MACRO_MAP;
5use crate::parse::pdxfile::{MacroComponent, MacroComponentKind, PdxfileMemory, parse_pdx_macro};
6use crate::token::{Loc, Token};
7
8mod blockitem;
9mod bv;
10mod comparator;
11mod field;
12
13pub use crate::block::blockitem::BlockItem;
14pub use crate::block::bv::BV;
15pub use crate::block::comparator::{Comparator, Eq};
16pub use crate::block::field::Field;
17
18#[derive(Clone, Debug)]
34pub struct Block {
35 v: Vec<BlockItem>,
37 pub tag: Option<Box<Token>>,
41 pub loc: Loc,
43 pub source: Option<Box<(Vec<MacroComponent>, PdxfileMemory)>>,
49}
50
51impl Block {
52 pub fn new(loc: Loc) -> Self {
54 Block { v: Vec::new(), tag: None, loc, source: None }
55 }
56
57 #[allow(dead_code)]
59 pub fn add_value(&mut self, value: Token) {
60 self.v.push(BlockItem::Value(value));
61 }
62
63 #[allow(dead_code)]
65 pub fn add_block(&mut self, block: Block) {
66 self.v.push(BlockItem::Block(block));
67 }
68
69 #[allow(dead_code)] pub fn add_key_bv(&mut self, key: Token, cmp: Comparator, value: BV) {
73 self.v.push(BlockItem::Field(Field(key, cmp, value)));
74 }
75
76 pub fn add_item(&mut self, item: BlockItem) {
79 self.v.push(item);
80 }
81
82 pub fn add_item_check_tag(&mut self, item: BlockItem) {
87 if let BlockItem::Block(mut block) = item {
88 if let Some(BlockItem::Field(Field(key, cmp, BV::Value(value)))) = self.v.last()
89 && (value.is("hsv")
90 || value.is("rgb")
91 || value.is("hsv360")
92 || value.is("cylindrical")
93 || value.is("cartesian"))
94 {
95 let key = key.clone();
96 let cmp = *cmp;
97 block.tag = Some(Box::new(value.clone()));
98 self.v.pop();
99 self.v.push(BlockItem::Field(Field(key, cmp, BV::Block(block))));
100 return;
101 }
102 self.v.push(BlockItem::Block(block));
103 } else {
104 self.v.push(item);
105 }
106 }
107
108 #[cfg(any(feature = "ck3", feature = "vic3", feature = "eu5"))]
111 pub fn append(&mut self, other: &mut Block) {
112 self.v.append(&mut other.v);
113 }
114
115 pub fn get_field_value(&self, name: &str) -> Option<&Token> {
117 for item in self.v.iter().rev() {
118 if let BlockItem::Field(Field(key, _, bv)) = item
119 && key.is(name)
120 {
121 match bv {
122 BV::Value(t) => return Some(t),
123 BV::Block(_) => (),
124 }
125 }
126 }
127 None
128 }
129
130 pub fn field_value_is(&self, name: &str, value: &str) -> bool {
132 if let Some(token) = self.get_field_value(name) { token.is(value) } else { false }
133 }
134
135 pub fn get_field_bool(&self, name: &str) -> Option<bool> {
137 self.get_field_value(name).map(|t| t.is("yes"))
138 }
139
140 #[allow(dead_code)] pub fn get_field_integer(&self, name: &str) -> Option<i64> {
143 self.get_field_value(name).and_then(Token::get_integer)
144 }
145
146 #[allow(dead_code)] pub fn get_field_date(&self, name: &str) -> Option<Date> {
149 self.get_field_value(name).and_then(Token::get_date)
150 }
151
152 pub fn get_field_values(&self, name: &str) -> Vec<&Token> {
156 let mut vec = Vec::new();
157 for (key, token) in self.iter_assignments() {
158 if key.is(name) {
159 vec.push(token);
160 }
161 }
162 vec
163 }
164
165 pub fn get_field_block(&self, name: &str) -> Option<&Block> {
167 for item in self.v.iter().rev() {
168 if let BlockItem::Field(Field(key, _, bv)) = item
169 && key.is(name)
170 {
171 match bv {
172 BV::Value(_) => (),
173 BV::Block(b) => return Some(b),
174 }
175 }
176 }
177 None
178 }
179
180 pub fn get_field_blocks(&self, name: &str) -> Vec<&Block> {
182 let mut vec = Vec::new();
183 for (key, block) in self.iter_definitions() {
184 if key.is(name) {
185 vec.push(block);
186 }
187 }
188 vec
189 }
190
191 pub fn get_field_list(&self, name: &str) -> Option<Vec<Token>> {
193 for item in self.v.iter().rev() {
194 if let BlockItem::Field(Field(key, _, bv)) = item
195 && key.is(name)
196 {
197 match bv {
198 BV::Value(_) => (),
199 BV::Block(b) => {
200 return Some(b.iter_values().cloned().collect());
201 }
202 }
203 }
204 }
205 None
206 }
207
208 #[allow(dead_code)] pub fn get_multi_field_list(&self, name: &str) -> Vec<Token> {
211 let mut vec = Vec::new();
212 for item in &self.v {
213 if let BlockItem::Field(Field(key, _, bv)) = item
214 && key.is(name)
215 {
216 match bv {
217 BV::Value(_) => (),
218 BV::Block(b) => {
219 vec.extend(b.iter_values().cloned());
220 }
221 }
222 }
223 }
224 vec
225 }
226
227 pub fn get_field(&self, name: &str) -> Option<&BV> {
229 for item in self.v.iter().rev() {
230 if let BlockItem::Field(Field(key, _, bv)) = item
231 && key.is(name)
232 {
233 return Some(bv);
234 }
235 }
236 None
237 }
238
239 pub fn get_key(&self, name: &str) -> Option<&Token> {
242 for item in self.v.iter().rev() {
243 if let BlockItem::Field(Field(key, _, _)) = item
244 && key.is(name)
245 {
246 return Some(key);
247 }
248 }
249 None
250 }
251
252 pub fn get_keys(&self, name: &str) -> Vec<&Token> {
255 let mut vec = Vec::new();
256 for Field(key, _, _) in self.iter_fields() {
257 if key.is(name) {
258 vec.push(key);
259 }
260 }
261 vec
262 }
263
264 pub fn has_key(&self, name: &str) -> bool {
266 self.get_key(name).is_some()
267 }
268
269 #[cfg(feature = "vic3")]
270 pub fn has_key_recursive(&self, name: &str) -> bool {
271 for item in &self.v {
272 match item {
273 BlockItem::Field(Field(key, _, bv)) => {
274 if key.is(name) {
275 return true;
276 }
277 if let Some(block) = bv.get_block()
278 && block.has_key_recursive(name)
279 {
280 return true;
281 }
282 }
283 BlockItem::Block(block) => {
284 if block.has_key_recursive(name) {
285 return true;
286 }
287 }
288 BlockItem::Value(_) => (),
289 }
290 }
291 false
292 }
293
294 #[allow(dead_code)] pub fn count_keys(&self, name: &str) -> usize {
297 let mut count = 0;
298 for Field(key, _, _) in self.iter_fields() {
299 if key.is(name) {
300 count += 1;
301 }
302 }
303 count
304 }
305
306 pub fn num_items(&self) -> usize {
308 self.v.len()
309 }
310
311 pub fn iter_items(&self) -> std::slice::Iter<'_, BlockItem> {
313 self.v.iter()
314 }
315
316 pub fn drain(&mut self) -> std::vec::Drain<'_, BlockItem> {
319 self.v.drain(..)
320 }
321
322 pub fn iter_fields(&self) -> IterFields<'_> {
325 IterFields { iter: self.v.iter(), warn: false }
326 }
327
328 #[allow(dead_code)] pub fn iter_fields_warn(&self) -> IterFields<'_> {
332 IterFields { iter: self.v.iter(), warn: true }
333 }
334
335 pub fn iter_assignments(&self) -> IterAssignments<'_> {
337 IterAssignments { iter: self.v.iter(), warn: false }
338 }
339
340 #[allow(dead_code)] pub fn iter_assignments_warn(&self) -> IterAssignments<'_> {
344 IterAssignments { iter: self.v.iter(), warn: true }
345 }
346
347 pub fn iter_definitions(&self) -> IterDefinitions<'_> {
349 IterDefinitions { iter: self.v.iter(), warn: false }
350 }
351
352 pub fn iter_definitions_warn(&self) -> IterDefinitions<'_> {
355 IterDefinitions { iter: self.v.iter(), warn: true }
356 }
357
358 #[allow(dead_code)] pub fn iter_assignments_and_definitions(&self) -> IterAssignmentsAndDefinitions<'_> {
363 IterAssignmentsAndDefinitions { iter: self.v.iter(), warn: false }
364 }
365
366 pub fn iter_assignments_and_definitions_warn(&self) -> IterAssignmentsAndDefinitions<'_> {
370 IterAssignmentsAndDefinitions { iter: self.v.iter(), warn: true }
371 }
372
373 pub fn drain_definitions_warn(&mut self) -> DrainDefinitions<'_> {
376 DrainDefinitions { iter: self.v.drain(..) }
377 }
378
379 #[allow(dead_code)] pub fn drain_assignments_warn(&mut self) -> DrainAssignments<'_> {
383 DrainAssignments { iter: self.v.drain(..) }
384 }
385
386 pub fn iter_values(&self) -> IterValues<'_> {
388 IterValues { iter: self.v.iter(), warn: false }
389 }
390
391 pub fn iter_values_warn(&self) -> IterValues<'_> {
393 IterValues { iter: self.v.iter(), warn: true }
394 }
395
396 #[allow(dead_code)]
398 pub fn iter_blocks(&self) -> IterBlocks<'_> {
399 IterBlocks { iter: self.v.iter(), warn: false }
400 }
401
402 #[allow(dead_code)] pub fn iter_blocks_warn(&self) -> IterBlocks<'_> {
405 IterBlocks { iter: self.v.iter(), warn: true }
406 }
407
408 #[allow(dead_code)] pub fn get_field_at_date(&self, name: &str, date: Date) -> Option<&BV> {
414 let mut found_date: Option<Date> = None;
415 let mut found: Option<&BV> = None;
416
417 for Field(key, _, bv) in self.iter_fields() {
418 if key.is(name) && found_date.is_none() {
419 found = Some(bv);
420 } else if let Ok(isdate) = Date::try_from(key)
421 && isdate <= date
422 && (found_date.is_none() || found_date.unwrap() < isdate)
423 && let Some(value) = bv.get_block().and_then(|b| b.get_field(name))
424 {
425 found_date = Some(isdate);
426 found = Some(value);
427 }
428 }
429 found
430 }
431
432 #[allow(dead_code)] pub fn get_field_value_at_date(&self, name: &str, date: Date) -> Option<&Token> {
435 self.get_field_at_date(name, date).and_then(BV::get_value)
436 }
437
438 pub fn macro_parms(&self) -> Vec<&'static str> {
441 if let Some(block_source) = &self.source {
442 let (ref source, _) = **block_source;
443 let mut vec = source
444 .iter()
445 .filter(|mc| mc.kind() == MacroComponentKind::Macro)
446 .map(|mc| mc.token().as_str())
447 .collect::<Vec<_>>();
448 vec.sort_unstable();
449 vec.dedup();
450 vec
451 } else {
452 Vec::new()
453 }
454 }
455
456 pub fn expand_macro(
459 &self,
460 args: &[(&str, Token)],
461 loc: Loc,
462 global: &PdxfileMemory,
463 ) -> Option<Block> {
464 let link_index = MACRO_MAP.get_or_insert_loc(loc);
465 if let Some(block_source) = &self.source {
466 let (ref source, ref local) = **block_source;
467 let mut content = Vec::new();
468 for part in source {
469 let token = part.token();
470 match part.kind() {
471 MacroComponentKind::Source => {
472 content.push(token.clone().linked(Some(link_index)));
473 }
474 MacroComponentKind::Macro => {
475 for (arg, val) in args {
476 if token.is(arg) {
477 let mut val = val.clone();
480 let orig_loc = val.loc;
481 val.loc = token.loc;
482 val.loc.column -= 1; val.loc.link_idx = Some(MACRO_MAP.get_or_insert_loc(orig_loc));
484 content.push(val);
485 break;
486 }
487 }
488 }
489 }
490 }
491 Some(parse_pdx_macro(&content, global, local))
492 } else {
493 None
494 }
495 }
496
497 pub fn equivalent(&self, other: &Self) -> bool {
500 if self.v.len() != other.v.len() {
501 return false;
502 }
503 for i in 0..self.v.len() {
504 if !self.v[i].equivalent(&other.v[i]) {
505 return false;
506 }
507 }
508 true
509 }
510
511 #[allow(dead_code)]
517 pub fn condense_tag(self, tag: &str) -> Self {
518 let mut other = Block::new(self.loc);
519 let mut reserve: Option<(Token, Comparator, Token)> = None;
520 for item in self.v {
521 if let Some((rkey, rcmp, mut rtoken)) = reserve {
522 if let BlockItem::Value(token) = item {
523 rtoken.combine(&token, '"');
525 other.add_key_bv(rkey, rcmp, BV::Value(rtoken));
526 reserve = None;
527 continue;
529 }
530 other.add_key_bv(rkey, rcmp, BV::Value(rtoken));
531 reserve = None;
532 }
533 if let BlockItem::Field(Field(key, cmp, bv)) = item {
534 match bv {
535 BV::Value(token) => {
536 if token.is(tag) {
537 reserve = Some((key, cmp, token));
538 continue;
539 }
540 other.add_key_bv(key, cmp, BV::Value(token));
541 }
542 BV::Block(block) => {
543 other.add_key_bv(key, cmp, BV::Block(block.condense_tag(tag)));
544 }
545 }
546 } else {
547 other.add_item(item);
548 }
549 }
550 other
551 }
552}
553
554#[derive(Clone, Debug)]
556pub struct IterAssignments<'a> {
557 iter: std::slice::Iter<'a, BlockItem>,
558 warn: bool,
559}
560
561impl<'a> Iterator for IterAssignments<'a> {
562 type Item = (&'a Token, &'a Token);
563
564 fn next(&mut self) -> Option<Self::Item> {
565 for item in self.iter.by_ref() {
566 if self.warn {
567 item.expect_assignment();
568 }
569 if let Some((key, token)) = item.get_assignment() {
570 return Some((key, token));
571 }
572 }
573 None
574 }
575}
576
577#[derive(Clone, Debug)]
579pub struct IterDefinitions<'a> {
580 iter: std::slice::Iter<'a, BlockItem>,
581 warn: bool,
582}
583
584impl<'a> Iterator for IterDefinitions<'a> {
585 type Item = (&'a Token, &'a Block);
586
587 fn next(&mut self) -> Option<Self::Item> {
588 for item in self.iter.by_ref() {
589 if self.warn {
590 item.expect_definition();
591 }
592 if let Some((key, block)) = item.get_definition() {
593 return Some((key, block));
594 }
595 }
596 None
597 }
598}
599
600#[derive(Clone, Debug)]
602pub struct IterAssignmentsAndDefinitions<'a> {
603 iter: std::slice::Iter<'a, BlockItem>,
604 warn: bool,
605}
606
607impl<'a> Iterator for IterAssignmentsAndDefinitions<'a> {
608 type Item = (&'a Token, &'a BV);
609
610 fn next(&mut self) -> Option<Self::Item> {
611 for item in self.iter.by_ref() {
612 if self.warn {
613 item.expect_field();
614 }
615 if let BlockItem::Field(field) = item {
616 if !field.is_eq() {
617 if self.warn {
618 field.expect_eq();
619 }
620 continue;
621 }
622 return Some((field.key(), field.bv()));
623 }
624 }
625 None
626 }
627}
628
629#[derive(Debug)]
632pub struct DrainDefinitions<'a> {
633 iter: std::vec::Drain<'a, BlockItem>,
634}
635
636impl Iterator for DrainDefinitions<'_> {
637 type Item = (Token, Block);
638
639 fn next(&mut self) -> Option<Self::Item> {
640 for item in self.iter.by_ref() {
641 if let Some((key, block)) = item.expect_into_definition() {
642 return Some((key, block));
643 }
644 }
645 None
646 }
647}
648
649#[derive(Debug)]
652pub struct DrainAssignments<'a> {
653 iter: std::vec::Drain<'a, BlockItem>,
654}
655
656impl Iterator for DrainAssignments<'_> {
657 type Item = (Token, Token);
658
659 fn next(&mut self) -> Option<Self::Item> {
660 for item in self.iter.by_ref() {
661 if let Some((key, value)) = item.expect_into_assignment() {
662 return Some((key, value));
663 }
664 }
665 None
666 }
667}
668
669#[derive(Clone, Debug)]
672pub struct IterFields<'a> {
673 iter: std::slice::Iter<'a, BlockItem>,
674 warn: bool,
675}
676
677impl<'a> Iterator for IterFields<'a> {
678 type Item = &'a Field;
679
680 fn next(&mut self) -> Option<Self::Item> {
681 for item in self.iter.by_ref() {
682 if self.warn {
683 item.expect_field();
684 }
685 if let BlockItem::Field(field) = item {
686 return Some(field);
687 }
688 }
689 None
690 }
691}
692
693#[derive(Clone, Debug)]
696pub struct IterValues<'a> {
697 iter: std::slice::Iter<'a, BlockItem>,
698 warn: bool,
699}
700
701impl<'a> Iterator for IterValues<'a> {
702 type Item = &'a Token;
703
704 fn next(&mut self) -> Option<Self::Item> {
705 for item in self.iter.by_ref() {
706 if self.warn {
707 item.expect_value();
708 }
709 if let BlockItem::Value(value) = item {
710 return Some(value);
711 }
712 }
713 None
714 }
715}
716
717#[derive(Clone, Debug)]
720pub struct IterBlocks<'a> {
721 iter: std::slice::Iter<'a, BlockItem>,
722 warn: bool,
723}
724
725impl<'a> Iterator for IterBlocks<'a> {
726 type Item = &'a Block;
727
728 fn next(&mut self) -> Option<Self::Item> {
729 for item in self.iter.by_ref() {
730 if self.warn {
731 item.expect_block();
732 }
733 if let BlockItem::Block(block) = item {
734 return Some(block);
735 }
736 }
737 None
738 }
739}