boseiju/ability_tree/imperative/
put_counters_imperative.rs

1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3
4const MAX_COUNTER_AMOUNT: usize = MAX_CHILDREN_PER_NODE - 1;
5
6/// Imperative to put counters on objects.
7#[derive(serde::Serialize, serde::Deserialize)]
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct PutCountersImperative {
10    pub object: crate::ability_tree::object::ObjectReference,
11    pub counters: crate::utils::HeapArrayVec<CounterOnPermanent, MAX_COUNTER_AMOUNT>,
12    #[cfg(feature = "spanned_tree")]
13    pub span: crate::ability_tree::span::TreeSpan,
14}
15
16impl AbilityTreeNode for PutCountersImperative {
17    fn node_id(&self) -> usize {
18        use idris::Idris;
19        crate::ability_tree::NodeKind::PutCountersImperative.id()
20    }
21
22    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
23        let mut children = arrayvec::ArrayVec::new_const();
24        children.push(&self.object as &dyn AbilityTreeNode);
25        for counter in self.counters.iter() {
26            children.push(counter as &dyn AbilityTreeNode);
27        }
28        children
29    }
30
31    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
32        use std::io::Write;
33        write!(out, "put counters:")?;
34        out.push_inter_branch()?;
35        write!(out, "on object:")?;
36        out.push_final_branch()?;
37        self.object.display(out)?;
38        out.pop_branch();
39        out.next_final_branch()?;
40        write!(out, "counters:")?;
41        for (i, counter) in self.counters.iter().enumerate() {
42            if i == self.counters.len() - 1 {
43                out.push_final_branch()?;
44            } else {
45                out.push_inter_branch()?;
46            }
47            counter.display(out)?;
48            out.pop_branch();
49        }
50        out.pop_branch();
51        Ok(())
52    }
53
54    fn node_tag(&self) -> &'static str {
55        "put counters imperative"
56    }
57
58    #[cfg(feature = "spanned_tree")]
59    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
60        self.span
61    }
62}
63
64#[cfg(feature = "parser")]
65impl crate::utils::DummyInit for PutCountersImperative {
66    fn dummy_init() -> Self {
67        Self {
68            object: crate::utils::dummy(),
69            counters: crate::utils::dummy(),
70            #[cfg(feature = "spanned_tree")]
71            span: Default::default(),
72        }
73    }
74}
75
76/// An amount and a kind of counters to be put on a permanent.
77#[derive(serde::Serialize, serde::Deserialize)]
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct CounterOnPermanent {
80    pub amount: crate::ability_tree::number::Number,
81    pub counter: CounterKind,
82    #[cfg(feature = "spanned_tree")]
83    pub span: crate::ability_tree::span::TreeSpan,
84}
85
86impl crate::ability_tree::AbilityTreeNode for CounterOnPermanent {
87    fn node_id(&self) -> usize {
88        use idris::Idris;
89        crate::ability_tree::NodeKind::CounterOnPermanent.id()
90    }
91
92    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
93        let mut children = arrayvec::ArrayVec::new_const();
94        children.push(&self.amount as &dyn AbilityTreeNode);
95        children.push(&self.counter as &dyn AbilityTreeNode);
96        children
97    }
98
99    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
100        use std::io::Write;
101        write!(out, "counter on permanent:")?;
102        out.push_inter_branch()?;
103        write!(out, "amount:")?;
104        out.push_final_branch()?;
105        self.amount.display(out)?;
106        out.pop_branch();
107        out.next_final_branch()?;
108        write!(out, "of counter:")?;
109        out.push_final_branch()?;
110        self.counter.display(out)?;
111        out.pop_branch();
112        out.pop_branch();
113        Ok(())
114    }
115
116    fn node_tag(&self) -> &'static str {
117        "counters on permanent"
118    }
119
120    #[cfg(feature = "spanned_tree")]
121    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
122        self.span
123    }
124}
125
126/// Kind of counter that is put on a permanent.
127///
128/// It's either a given kind of counter, e.g. "put a shield counter" or
129/// a previously mentionned kind of counter, e.g. "that many counters on...".
130#[derive(serde::Serialize, serde::Deserialize)]
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub enum CounterKind {
133    PreviouslyMentionnedCounter {
134        #[cfg(feature = "spanned_tree")]
135        span: crate::ability_tree::span::TreeSpan,
136    },
137    NewCounter(crate::ability_tree::terminals::Counter),
138}
139
140#[cfg(feature = "spanned_tree")]
141impl CounterKind {
142    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
143        match self {
144            Self::PreviouslyMentionnedCounter { span } => *span,
145            Self::NewCounter(child) => child.span,
146        }
147    }
148}
149
150impl AbilityTreeNode for CounterKind {
151    fn node_id(&self) -> usize {
152        use idris::Idris;
153        crate::ability_tree::NodeKind::CounterKind.id()
154    }
155
156    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
157        use idris::Idris;
158
159        let mut children = arrayvec::ArrayVec::new_const();
160        match self {
161            Self::PreviouslyMentionnedCounter { .. } => {
162                children.push(crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::new(
163                    crate::ability_tree::NodeKind::PreviouslyMentionnedCounter.id(),
164                ) as &dyn AbilityTreeNode)
165            }
166            Self::NewCounter(counter) => children.push(counter as &dyn AbilityTreeNode),
167        }
168        children
169    }
170
171    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
172        use std::io::Write;
173        write!(out, "counter kind:")?;
174        out.push_final_branch()?;
175        match self {
176            Self::PreviouslyMentionnedCounter { .. } => write!(out, "previously mentionned counter")?,
177            Self::NewCounter(counter) => counter.display(out)?,
178        }
179        out.pop_branch();
180        Ok(())
181    }
182
183    fn node_tag(&self) -> &'static str {
184        "counter kind"
185    }
186
187    #[cfg(feature = "spanned_tree")]
188    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
189        match self {
190            Self::PreviouslyMentionnedCounter { span } => *span,
191            Self::NewCounter(child) => child.node_span(),
192        }
193    }
194}
195
196#[cfg(feature = "parser")]
197impl crate::utils::DummyInit for CounterKind {
198    fn dummy_init() -> Self {
199        Self::PreviouslyMentionnedCounter {
200            #[cfg(feature = "spanned_tree")]
201            span: Default::default(),
202        }
203    }
204}