boseiju/ability_tree/terminals/
mana_cost.rs1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3use crate::lexer::IntoToken;
4
5#[derive(serde::Serialize, serde::Deserialize)]
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct ManaCost {
11 pub cost: arrayvec::ArrayVec<crate::ability_tree::terminals::Mana, MAX_CHILDREN_PER_NODE>,
12 #[cfg(feature = "spanned_tree")]
13 pub span: crate::ability_tree::span::TreeSpan,
14}
15
16impl ManaCost {
17 pub fn mana_value(&self) -> usize {
18 self.cost.iter().map(|mana| mana.mana_value()).sum()
19 }
20}
21
22impl AbilityTreeNode for ManaCost {
23 fn node_id(&self) -> usize {
24 use idris::Idris;
25 crate::ability_tree::NodeKind::ManaCost.id()
26 }
27
28 fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
29 let mut children = arrayvec::ArrayVec::new_const();
30 for cost in self.cost.iter() {
31 children.push(cost as &dyn AbilityTreeNode);
32 }
33 children
34 }
35
36 fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
37 use std::io::Write;
38 write!(out, "mana cost: ")?;
39 for mana in self.cost.iter() {
40 mana.display(out)?;
41 }
42 Ok(())
43 }
44
45 fn node_tag(&self) -> &'static str {
46 "mana cost"
47 }
48
49 #[cfg(feature = "spanned_tree")]
50 fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
51 self.span
52 }
53}
54
55impl IntoToken for ManaCost {
56 fn try_from_span(span: &crate::lexer::Span) -> Option<Self> {
57 let mut cost = arrayvec::ArrayVec::new_const();
58 lazy_static::lazy_static!(
60 static ref mana_cost_regex: regex::Regex = regex::Regex::new(r"(\{[^{}]+\})")
61 .expect("Failed to compile the mana cost iterator regex: {e}");
62 );
63
64 for capture in mana_cost_regex.captures_iter(&span.text) {
65 let span = crate::lexer::Span {
66 start: span.start + capture.get_match().start(),
67 length: capture.get_match().len(),
68 text: capture.get_match().as_str(),
69 };
70 let mana = crate::ability_tree::terminals::Mana::try_from_span(&span)?;
71 cost.push(mana);
72 }
73
74 Some(ManaCost {
75 cost,
76 #[cfg(feature = "spanned_tree")]
77 span: span.into(),
78 })
79 }
80}
81
82impl std::ops::Deref for ManaCost {
83 type Target = [crate::ability_tree::terminals::Mana];
84 fn deref(&self) -> &Self::Target {
85 self.cost.as_slice()
86 }
87}
88
89impl std::ops::DerefMut for ManaCost {
90 fn deref_mut(&mut self) -> &mut Self::Target {
91 self.cost.as_mut_slice()
92 }
93}
94
95#[cfg(feature = "parser")]
96impl crate::utils::DummyInit for ManaCost {
97 fn dummy_init() -> Self {
98 Self {
99 cost: crate::utils::dummy(),
100 #[cfg(feature = "spanned_tree")]
101 span: Default::default(),
102 }
103 }
104}