boseiju/ability_tree/ability/
spell.rs

1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3
4/// A spell ability.
5///
6/// From the comprehensive rules 113.3a:
7/// Spell abilities are abilities that are followed as instructions while an
8/// instant or sorcery spell is resolving. Any text on an instant or sorcery spell
9/// is a spell ability unless it's an activated ability, a triggered ability,
10/// or a static ability that fits the criteria described in rule 113.6.
11///
12/// Spell abilities are represented as a list of statements that are all of the spell effects.
13#[derive(serde::Serialize, serde::Deserialize)]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct SpellAbility {
16    pub effects: crate::utils::HeapArrayVec<crate::ability_tree::statement::Statement, MAX_CHILDREN_PER_NODE>,
17    #[cfg(feature = "spanned_tree")]
18    pub span: crate::ability_tree::span::TreeSpan,
19}
20
21impl crate::ability_tree::AbilityTreeNode for SpellAbility {
22    fn node_id(&self) -> usize {
23        use idris::Idris;
24        crate::ability_tree::NodeKind::SpellAbility.id()
25    }
26
27    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
28        let mut children = arrayvec::ArrayVec::new_const();
29        for child in self.effects.iter() {
30            children.push(child as &dyn AbilityTreeNode);
31        }
32        children
33    }
34
35    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
36        use std::io::Write;
37        write!(out, "spell ability:")?;
38        for effect in self.effects.iter().take(self.effects.len().saturating_sub(1)) {
39            out.push_inter_branch()?;
40            effect.display(out)?;
41            out.pop_branch();
42        }
43        if let Some(effect) = self.effects.last() {
44            out.push_final_branch()?;
45            effect.display(out)?;
46            out.pop_branch();
47        }
48        Ok(())
49    }
50
51    fn node_tag(&self) -> &'static str {
52        "spell ability"
53    }
54
55    #[cfg(feature = "spanned_tree")]
56    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
57        self.span
58    }
59}
60
61#[cfg(feature = "parser")]
62impl crate::utils::DummyInit for SpellAbility {
63    fn dummy_init() -> Self {
64        Self {
65            effects: crate::utils::dummy(),
66            #[cfg(feature = "spanned_tree")]
67            span: Default::default(),
68        }
69    }
70}