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 if 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 }
103 self.v.push(BlockItem::Block(block));
104 } else {
105 self.v.push(item);
106 }
107 }
108
109 #[cfg(any(feature = "ck3", feature = "vic3", feature = "eu5"))]
112 pub fn append(&mut self, other: &mut Block) {
113 self.v.append(&mut other.v);
114 }
115
116 pub fn get_field_value(&self, name: &str) -> Option<&Token> {
118 for item in self.v.iter().rev() {
119 if let BlockItem::Field(Field(key, _, bv)) = item {
120 if key.is(name) {
121 match bv {
122 BV::Value(t) => return Some(t),
123 BV::Block(_) => (),
124 }
125 }
126 }
127 }
128 None
129 }
130
131 pub fn field_value_is(&self, name: &str, value: &str) -> bool {
133 if let Some(token) = self.get_field_value(name) { token.is(value) } else { false }
134 }
135
136 pub fn get_field_bool(&self, name: &str) -> Option<bool> {
138 self.get_field_value(name).map(|t| t.is("yes"))
139 }
140
141 #[allow(dead_code)] pub fn get_field_integer(&self, name: &str) -> Option<i64> {
144 self.get_field_value(name).and_then(Token::get_integer)
145 }
146
147 #[allow(dead_code)] pub fn get_field_date(&self, name: &str) -> Option<Date> {
150 self.get_field_value(name).and_then(Token::get_date)
151 }
152
153 pub fn get_field_values(&self, name: &str) -> Vec<&Token> {
157 let mut vec = Vec::new();
158 for (key, token) in self.iter_assignments() {
159 if key.is(name) {
160 vec.push(token);
161 }
162 }
163 vec
164 }
165
166 pub fn get_field_block(&self, name: &str) -> Option<&Block> {
168 for item in self.v.iter().rev() {
169 if let BlockItem::Field(Field(key, _, bv)) = item {
170 if key.is(name) {
171 match bv {
172 BV::Value(_) => (),
173 BV::Block(b) => return Some(b),
174 }
175 }
176 }
177 }
178 None
179 }
180
181 pub fn get_field_blocks(&self, name: &str) -> Vec<&Block> {
183 let mut vec = Vec::new();
184 for (key, block) in self.iter_definitions() {
185 if key.is(name) {
186 vec.push(block);
187 }
188 }
189 vec
190 }
191
192 pub fn get_field_list(&self, name: &str) -> Option<Vec<Token>> {
194 for item in self.v.iter().rev() {
195 if let BlockItem::Field(Field(key, _, bv)) = item {
196 if key.is(name) {
197 match bv {
198 BV::Value(_) => (),
199 BV::Block(b) => {
200 return Some(b.iter_values().cloned().collect());
201 }
202 }
203 }
204 }
205 }
206 None
207 }
208
209 #[allow(dead_code)] pub fn get_multi_field_list(&self, name: &str) -> Vec<Token> {
212 let mut vec = Vec::new();
213 for item in &self.v {
214 if let BlockItem::Field(Field(key, _, bv)) = item {
215 if key.is(name) {
216 match bv {
217 BV::Value(_) => (),
218 BV::Block(b) => {
219 vec.extend(b.iter_values().cloned());
220 }
221 }
222 }
223 }
224 }
225 vec
226 }
227
228 pub fn get_field(&self, name: &str) -> Option<&BV> {
230 for item in self.v.iter().rev() {
231 if let BlockItem::Field(Field(key, _, bv)) = item {
232 if key.is(name) {
233 return Some(bv);
234 }
235 }
236 }
237 None
238 }
239
240 pub fn get_key(&self, name: &str) -> Option<&Token> {
243 for item in self.v.iter().rev() {
244 if let BlockItem::Field(Field(key, _, _)) = item {
245 if key.is(name) {
246 return Some(key);
247 }
248 }
249 }
250 None
251 }
252
253 pub fn get_keys(&self, name: &str) -> Vec<&Token> {
256 let mut vec = Vec::new();
257 for Field(key, _, _) in self.iter_fields() {
258 if key.is(name) {
259 vec.push(key);
260 }
261 }
262 vec
263 }
264
265 pub fn has_key(&self, name: &str) -> bool {
267 self.get_key(name).is_some()
268 }
269
270 #[cfg(feature = "vic3")]
271 pub fn has_key_recursive(&self, name: &str) -> bool {
272 for item in &self.v {
273 match item {
274 BlockItem::Field(Field(key, _, bv)) => {
275 if key.is(name) {
276 return true;
277 }
278 if let Some(block) = bv.get_block() {
279 if block.has_key_recursive(name) {
280 return true;
281 }
282 }
283 }
284 BlockItem::Block(block) => {
285 if block.has_key_recursive(name) {
286 return true;
287 }
288 }
289 BlockItem::Value(_) => (),
290 }
291 }
292 false
293 }
294
295 #[allow(dead_code)] pub fn count_keys(&self, name: &str) -> usize {
298 let mut count = 0;
299 for Field(key, _, _) in self.iter_fields() {
300 if key.is(name) {
301 count += 1;
302 }
303 }
304 count
305 }
306
307 pub fn num_items(&self) -> usize {
309 self.v.len()
310 }
311
312 pub fn iter_items(&self) -> std::slice::Iter<'_, BlockItem> {
314 self.v.iter()
315 }
316
317 pub fn drain(&mut self) -> std::vec::Drain<'_, BlockItem> {
320 self.v.drain(..)
321 }
322
323 pub fn iter_fields(&self) -> IterFields<'_> {
326 IterFields { iter: self.v.iter(), warn: false }
327 }
328
329 #[allow(dead_code)] pub fn iter_fields_warn(&self) -> IterFields<'_> {
333 IterFields { iter: self.v.iter(), warn: true }
334 }
335
336 pub fn iter_assignments(&self) -> IterAssignments<'_> {
338 IterAssignments { iter: self.v.iter(), warn: false }
339 }
340
341 #[allow(dead_code)] pub fn iter_assignments_warn(&self) -> IterAssignments<'_> {
345 IterAssignments { iter: self.v.iter(), warn: true }
346 }
347
348 pub fn iter_definitions(&self) -> IterDefinitions<'_> {
350 IterDefinitions { iter: self.v.iter(), warn: false }
351 }
352
353 pub fn iter_definitions_warn(&self) -> IterDefinitions<'_> {
356 IterDefinitions { iter: self.v.iter(), warn: true }
357 }
358
359 #[allow(dead_code)] pub fn iter_assignments_and_definitions(&self) -> IterAssignmentsAndDefinitions<'_> {
364 IterAssignmentsAndDefinitions { iter: self.v.iter(), warn: false }
365 }
366
367 pub fn iter_assignments_and_definitions_warn(&self) -> IterAssignmentsAndDefinitions<'_> {
371 IterAssignmentsAndDefinitions { iter: self.v.iter(), warn: true }
372 }
373
374 pub fn drain_definitions_warn(&mut self) -> DrainDefinitions<'_> {
377 DrainDefinitions { iter: self.v.drain(..) }
378 }
379
380 #[allow(dead_code)] pub fn drain_assignments_warn(&mut self) -> DrainAssignments<'_> {
384 DrainAssignments { iter: self.v.drain(..) }
385 }
386
387 pub fn iter_values(&self) -> IterValues<'_> {
389 IterValues { iter: self.v.iter(), warn: false }
390 }
391
392 pub fn iter_values_warn(&self) -> IterValues<'_> {
394 IterValues { iter: self.v.iter(), warn: true }
395 }
396
397 #[allow(dead_code)]
399 pub fn iter_blocks(&self) -> IterBlocks<'_> {
400 IterBlocks { iter: self.v.iter(), warn: false }
401 }
402
403 #[allow(dead_code)] pub fn iter_blocks_warn(&self) -> IterBlocks<'_> {
406 IterBlocks { iter: self.v.iter(), warn: true }
407 }
408
409 #[allow(dead_code)] pub fn get_field_at_date(&self, name: &str, date: Date) -> Option<&BV> {
415 let mut found_date: Option<Date> = None;
416 let mut found: Option<&BV> = None;
417
418 for Field(key, _, bv) in self.iter_fields() {
419 if key.is(name) && found_date.is_none() {
420 found = Some(bv);
421 } else if let Ok(isdate) = Date::try_from(key) {
422 if isdate <= date && (found_date.is_none() || found_date.unwrap() < isdate) {
423 if let Some(value) = bv.get_block().and_then(|b| b.get_field(name)) {
424 found_date = Some(isdate);
425 found = Some(value);
426 }
427 }
428 }
429 }
430 found
431 }
432
433 #[allow(dead_code)] pub fn get_field_value_at_date(&self, name: &str, date: Date) -> Option<&Token> {
436 self.get_field_at_date(name, date).and_then(BV::get_value)
437 }
438
439 pub fn macro_parms(&self) -> Vec<&'static str> {
442 if let Some(block_source) = &self.source {
443 let (ref source, _) = **block_source;
444 let mut vec = source
445 .iter()
446 .filter(|mc| mc.kind() == MacroComponentKind::Macro)
447 .map(|mc| mc.token().as_str())
448 .collect::<Vec<_>>();
449 vec.sort_unstable();
450 vec.dedup();
451 vec
452 } else {
453 Vec::new()
454 }
455 }
456
457 pub fn expand_macro(
460 &self,
461 args: &[(&str, Token)],
462 loc: Loc,
463 global: &PdxfileMemory,
464 ) -> Option<Block> {
465 let link_index = MACRO_MAP.get_or_insert_loc(loc);
466 if let Some(block_source) = &self.source {
467 let (ref source, ref local) = **block_source;
468 let mut content = Vec::new();
469 for part in source {
470 let token = part.token();
471 match part.kind() {
472 MacroComponentKind::Source => {
473 content.push(token.clone().linked(Some(link_index)));
474 }
475 MacroComponentKind::Macro => {
476 for (arg, val) in args {
477 if token.is(arg) {
478 let mut val = val.clone();
481 let orig_loc = val.loc;
482 val.loc = token.loc;
483 val.loc.column -= 1; val.loc.link_idx = Some(MACRO_MAP.get_or_insert_loc(orig_loc));
485 content.push(val);
486 break;
487 }
488 }
489 }
490 }
491 }
492 Some(parse_pdx_macro(&content, global, local))
493 } else {
494 None
495 }
496 }
497
498 pub fn equivalent(&self, other: &Self) -> bool {
501 if self.v.len() != other.v.len() {
502 return false;
503 }
504 for i in 0..self.v.len() {
505 if !self.v[i].equivalent(&other.v[i]) {
506 return false;
507 }
508 }
509 true
510 }
511
512 #[allow(dead_code)]
518 pub fn condense_tag(self, tag: &str) -> Self {
519 let mut other = Block::new(self.loc);
520 let mut reserve: Option<(Token, Comparator, Token)> = None;
521 for item in self.v {
522 if let Some((rkey, rcmp, mut rtoken)) = reserve {
523 if let BlockItem::Value(token) = item {
524 rtoken.combine(&token, '"');
526 other.add_key_bv(rkey, rcmp, BV::Value(rtoken));
527 reserve = None;
528 continue;
530 }
531 other.add_key_bv(rkey, rcmp, BV::Value(rtoken));
532 reserve = None;
533 }
534 if let BlockItem::Field(Field(key, cmp, bv)) = item {
535 match bv {
536 BV::Value(token) => {
537 if token.is(tag) {
538 reserve = Some((key, cmp, token));
539 continue;
540 }
541 other.add_key_bv(key, cmp, BV::Value(token));
542 }
543 BV::Block(block) => {
544 other.add_key_bv(key, cmp, BV::Block(block.condense_tag(tag)));
545 }
546 }
547 } else {
548 other.add_item(item);
549 }
550 }
551 other
552 }
553}
554
555#[derive(Clone, Debug)]
557pub struct IterAssignments<'a> {
558 iter: std::slice::Iter<'a, BlockItem>,
559 warn: bool,
560}
561
562impl<'a> Iterator for IterAssignments<'a> {
563 type Item = (&'a Token, &'a Token);
564
565 fn next(&mut self) -> Option<Self::Item> {
566 for item in self.iter.by_ref() {
567 if self.warn {
568 item.expect_assignment();
569 }
570 if let Some((key, token)) = item.get_assignment() {
571 return Some((key, token));
572 }
573 }
574 None
575 }
576}
577
578#[derive(Clone, Debug)]
580pub struct IterDefinitions<'a> {
581 iter: std::slice::Iter<'a, BlockItem>,
582 warn: bool,
583}
584
585impl<'a> Iterator for IterDefinitions<'a> {
586 type Item = (&'a Token, &'a Block);
587
588 fn next(&mut self) -> Option<Self::Item> {
589 for item in self.iter.by_ref() {
590 if self.warn {
591 item.expect_definition();
592 }
593 if let Some((key, block)) = item.get_definition() {
594 return Some((key, block));
595 }
596 }
597 None
598 }
599}
600
601#[derive(Clone, Debug)]
603pub struct IterAssignmentsAndDefinitions<'a> {
604 iter: std::slice::Iter<'a, BlockItem>,
605 warn: bool,
606}
607
608impl<'a> Iterator for IterAssignmentsAndDefinitions<'a> {
609 type Item = (&'a Token, &'a BV);
610
611 fn next(&mut self) -> Option<Self::Item> {
612 for item in self.iter.by_ref() {
613 if self.warn {
614 item.expect_field();
615 }
616 if let BlockItem::Field(field) = item {
617 if !field.is_eq() {
618 if self.warn {
619 field.expect_eq();
620 }
621 continue;
622 }
623 return Some((field.key(), field.bv()));
624 }
625 }
626 None
627 }
628}
629
630#[derive(Debug)]
633pub struct DrainDefinitions<'a> {
634 iter: std::vec::Drain<'a, BlockItem>,
635}
636
637impl Iterator for DrainDefinitions<'_> {
638 type Item = (Token, Block);
639
640 fn next(&mut self) -> Option<Self::Item> {
641 for item in self.iter.by_ref() {
642 if let Some((key, block)) = item.expect_into_definition() {
643 return Some((key, block));
644 }
645 }
646 None
647 }
648}
649
650#[derive(Debug)]
653pub struct DrainAssignments<'a> {
654 iter: std::vec::Drain<'a, BlockItem>,
655}
656
657impl Iterator for DrainAssignments<'_> {
658 type Item = (Token, Token);
659
660 fn next(&mut self) -> Option<Self::Item> {
661 for item in self.iter.by_ref() {
662 if let Some((key, value)) = item.expect_into_assignment() {
663 return Some((key, value));
664 }
665 }
666 None
667 }
668}
669
670#[derive(Clone, Debug)]
673pub struct IterFields<'a> {
674 iter: std::slice::Iter<'a, BlockItem>,
675 warn: bool,
676}
677
678impl<'a> Iterator for IterFields<'a> {
679 type Item = &'a Field;
680
681 fn next(&mut self) -> Option<Self::Item> {
682 for item in self.iter.by_ref() {
683 if self.warn {
684 item.expect_field();
685 }
686 if let BlockItem::Field(field) = item {
687 return Some(field);
688 }
689 }
690 None
691 }
692}
693
694#[derive(Clone, Debug)]
697pub struct IterValues<'a> {
698 iter: std::slice::Iter<'a, BlockItem>,
699 warn: bool,
700}
701
702impl<'a> Iterator for IterValues<'a> {
703 type Item = &'a Token;
704
705 fn next(&mut self) -> Option<Self::Item> {
706 for item in self.iter.by_ref() {
707 if self.warn {
708 item.expect_value();
709 }
710 if let BlockItem::Value(value) = item {
711 return Some(value);
712 }
713 }
714 None
715 }
716}
717
718#[derive(Clone, Debug)]
721pub struct IterBlocks<'a> {
722 iter: std::slice::Iter<'a, BlockItem>,
723 warn: bool,
724}
725
726impl<'a> Iterator for IterBlocks<'a> {
727 type Item = &'a Block;
728
729 fn next(&mut self) -> Option<Self::Item> {
730 for item in self.iter.by_ref() {
731 if self.warn {
732 item.expect_block();
733 }
734 if let BlockItem::Block(block) = item {
735 return Some(block);
736 }
737 }
738 None
739 }
740}