boseiju/ability_tree/ability/
keyword.rs

1mod keyword_to_abilities;
2
3pub use keyword_to_abilities::keyword_to_abilities;
4
5use crate::ability_tree::AbilityTreeNode;
6use crate::ability_tree::MAX_CHILDREN_PER_NODE;
7
8/// This is basically a 1-1 copy of the [`mtg_data::KeywordAbility`],
9/// expect all keyword abilities required additional text also have this text.
10///
11/// For instance, "Ward" on its own isn't truly a keyword abilty: It's "ward: pay 2 life".
12#[derive(idris_derive::Idris)]
13#[derive(serde::Serialize, serde::Deserialize)]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum ExpandedKeywordAbility {
16    Enchant(EnchantKeywordAbility),
17    Standalone(StandaloneKeywordAbility),
18    Ward(WardKeywordAbility),
19}
20
21impl crate::ability_tree::AbilityTreeNode for ExpandedKeywordAbility {
22    fn node_id(&self) -> usize {
23        use idris::Idris;
24        crate::ability_tree::NodeKind::ExpandedKeywordAbilityIdMarker.id()
25    }
26
27    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
28        let mut children = arrayvec::ArrayVec::new_const();
29        match self {
30            Self::Ward(child) => children.push(child as &dyn AbilityTreeNode),
31            Self::Enchant(child) => children.push(child as &dyn AbilityTreeNode),
32            Self::Standalone(child) => children.push(child as &dyn AbilityTreeNode),
33        }
34        children
35    }
36
37    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
38        use std::io::Write;
39        write!(out, "keyword ability:")?;
40        out.push_final_branch()?;
41        match self {
42            Self::Ward(child) => child.display(out)?,
43            Self::Enchant(child) => child.display(out)?,
44            Self::Standalone(child) => child.display(out)?,
45        }
46        out.pop_branch();
47        Ok(())
48    }
49
50    fn node_tag(&self) -> &'static str {
51        "keyword ability"
52    }
53
54    #[cfg(feature = "spanned_tree")]
55    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
56        match self {
57            Self::Enchant(child) => child.node_span(),
58            Self::Standalone(child) => child.node_span(),
59            Self::Ward(child) => child.node_span(),
60        }
61    }
62}
63
64#[cfg(feature = "parser")]
65impl crate::utils::DummyInit for ExpandedKeywordAbility {
66    fn dummy_init() -> Self {
67        Self::Standalone(crate::utils::dummy())
68    }
69}
70
71/// Wrapper around the mtg type for the standalone keyword ability.
72#[derive(serde::Serialize, serde::Deserialize)]
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub struct StandaloneKeywordAbility {
75    pub keyword_ability: crate::ability_tree::terminals::StandaloneKeywordAbility,
76    #[cfg(feature = "spanned_tree")]
77    pub span: crate::ability_tree::span::TreeSpan,
78}
79
80impl AbilityTreeNode for StandaloneKeywordAbility {
81    fn node_id(&self) -> usize {
82        use idris::Idris;
83        crate::ability_tree::NodeKind::ExpandedKeywordAbility(self.keyword_ability.clone()).id()
84    }
85
86    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
87        use idris::Idris;
88        let mut children = arrayvec::ArrayVec::new_const();
89        let child_id = crate::ability_tree::NodeKind::ExpandedKeywordAbility(self.keyword_ability.clone()).id();
90        let child = crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::new(child_id);
91        children.push(child as &dyn AbilityTreeNode);
92        children
93    }
94
95    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
96        use std::io::Write;
97        write!(out, "standalone: {}", self.keyword_ability)
98    }
99
100    fn node_tag(&self) -> &'static str {
101        "standalone keyword ability"
102    }
103
104    #[cfg(feature = "spanned_tree")]
105    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
106        self.span
107    }
108}
109
110impl idris::Idris for StandaloneKeywordAbility {
111    const COUNT: usize = crate::ability_tree::terminals::StandaloneKeywordAbility::COUNT;
112    fn id(&self) -> usize {
113        self.keyword_ability.id()
114    }
115    fn name_from_id(id: usize) -> &'static str {
116        crate::ability_tree::terminals::StandaloneKeywordAbility::name_from_id(id)
117    }
118}
119
120#[cfg(feature = "parser")]
121impl crate::utils::DummyInit for StandaloneKeywordAbility {
122    fn dummy_init() -> Self {
123        Self {
124            keyword_ability: crate::ability_tree::terminals::StandaloneKeywordAbility::Haste,
125            #[cfg(feature = "spanned_tree")]
126            span: Default::default(),
127        }
128    }
129}
130
131#[derive(serde::Serialize, serde::Deserialize)]
132#[derive(Debug, Clone, PartialEq, Eq)]
133pub struct WardKeywordAbility {
134    pub cost: crate::ability_tree::cost::Cost,
135    #[cfg(feature = "spanned_tree")]
136    pub span: crate::ability_tree::span::TreeSpan,
137}
138
139impl crate::ability_tree::AbilityTreeNode for WardKeywordAbility {
140    fn node_id(&self) -> usize {
141        use crate::ability_tree::tree_node::KeywordAbilityNodeKind;
142        use idris::Idris;
143
144        crate::ability_tree::NodeKind::KeywordAbility(KeywordAbilityNodeKind::Ward).id()
145    }
146
147    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
148        let mut children = arrayvec::ArrayVec::new_const();
149        children.push(&self.cost as &dyn AbilityTreeNode);
150        children
151    }
152
153    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
154        use std::io::Write;
155        write!(out, "ward—")?;
156        self.cost.display(out)?;
157        Ok(())
158    }
159
160    fn node_tag(&self) -> &'static str {
161        "ward keyword ability"
162    }
163
164    #[cfg(feature = "spanned_tree")]
165    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
166        self.span
167    }
168}
169
170impl idris::Idris for WardKeywordAbility {
171    const COUNT: usize = 1;
172    fn id(&self) -> usize {
173        0
174    }
175    fn name_from_id(_: usize) -> &'static str {
176        "ward"
177    }
178}
179
180#[cfg(feature = "parser")]
181impl crate::utils::DummyInit for WardKeywordAbility {
182    fn dummy_init() -> WardKeywordAbility {
183        Self {
184            cost: crate::utils::dummy(),
185            #[cfg(feature = "spanned_tree")]
186            span: Default::default(),
187        }
188    }
189}
190
191#[derive(serde::Serialize, serde::Deserialize)]
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct EnchantKeywordAbility {
194    pub enchantable_object: crate::ability_tree::object::ObjectSpecifiers,
195    #[cfg(feature = "spanned_tree")]
196    pub span: crate::ability_tree::span::TreeSpan,
197}
198
199impl crate::ability_tree::AbilityTreeNode for EnchantKeywordAbility {
200    fn node_id(&self) -> usize {
201        use crate::ability_tree::tree_node::KeywordAbilityNodeKind;
202        use idris::Idris;
203
204        crate::ability_tree::NodeKind::KeywordAbility(KeywordAbilityNodeKind::Enchant).id()
205    }
206
207    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
208        let mut children = arrayvec::ArrayVec::new_const();
209        children.push(&self.enchantable_object as &dyn AbilityTreeNode);
210        children
211    }
212
213    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
214        use std::io::Write;
215        write!(out, "ward—")?;
216        self.enchantable_object.display(out)?;
217        Ok(())
218    }
219
220    fn node_tag(&self) -> &'static str {
221        "enchant keyword ability"
222    }
223
224    #[cfg(feature = "spanned_tree")]
225    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
226        self.span
227    }
228}
229
230impl idris::Idris for EnchantKeywordAbility {
231    const COUNT: usize = 1;
232    fn id(&self) -> usize {
233        0
234    }
235    fn name_from_id(_: usize) -> &'static str {
236        "ward"
237    }
238}
239
240#[cfg(feature = "parser")]
241impl crate::utils::DummyInit for EnchantKeywordAbility {
242    fn dummy_init() -> Self {
243        Self {
244            enchantable_object: crate::utils::dummy(),
245            #[cfg(feature = "spanned_tree")]
246            span: Default::default(),
247        }
248    }
249}