boseiju/ability_tree/imperative/
remove_counters_imperative.rs1use 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#[derive(serde::Serialize, serde::Deserialize)]
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct RemoveCountersImperative {
10 pub object: crate::ability_tree::object::ObjectReference,
11 pub counters: crate::utils::HeapArrayVec<RemovableCounterOnPermanent, MAX_COUNTER_AMOUNT>,
12 #[cfg(feature = "spanned_tree")]
13 pub span: crate::ability_tree::span::TreeSpan,
14}
15
16impl AbilityTreeNode for RemoveCountersImperative {
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, "remove 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 "remove 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 RemoveCountersImperative {
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#[derive(serde::Serialize, serde::Deserialize)]
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct RemovableCounterOnPermanent {
80 pub amount: crate::ability_tree::number::Number,
81 pub counter: RemovableCounterKind,
82 #[cfg(feature = "spanned_tree")]
83 pub span: crate::ability_tree::span::TreeSpan,
84}
85
86impl crate::ability_tree::AbilityTreeNode for RemovableCounterOnPermanent {
87 fn node_id(&self) -> usize {
88 use idris::Idris;
89 crate::ability_tree::NodeKind::RemovableCounterOnPermanent.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 "removable counter from 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#[derive(serde::Serialize, serde::Deserialize)]
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub enum RemovableCounterKind {
133 AnyCounter {
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 RemovableCounterKind {
142 pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
143 match self {
144 Self::AnyCounter { span } => *span,
145 Self::NewCounter(child) => child.span,
146 }
147 }
148}
149
150impl AbilityTreeNode for RemovableCounterKind {
151 fn node_id(&self) -> usize {
152 use idris::Idris;
153 crate::ability_tree::NodeKind::RemovableCounterKind.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::AnyCounter { .. } => children.push(crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::new(
162 crate::ability_tree::NodeKind::PreviouslyMentionnedCounter.id(),
163 ) as &dyn AbilityTreeNode),
164 Self::NewCounter(counter) => children.push(counter as &dyn AbilityTreeNode),
165 }
166 children
167 }
168
169 fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
170 use std::io::Write;
171 write!(out, "counter kind:")?;
172 out.push_final_branch()?;
173 match self {
174 Self::AnyCounter { .. } => write!(out, "any kind of counter")?,
175 Self::NewCounter(counter) => counter.display(out)?,
176 }
177 out.pop_branch();
178 Ok(())
179 }
180
181 fn node_tag(&self) -> &'static str {
182 "removable counter kind"
183 }
184
185 #[cfg(feature = "spanned_tree")]
186 fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
187 match self {
188 Self::AnyCounter { span } => *span,
189 Self::NewCounter(child) => child.node_span(),
190 }
191 }
192}
193
194#[cfg(feature = "parser")]
195impl crate::utils::DummyInit for RemovableCounterKind {
196 fn dummy_init() -> Self {
197 Self::AnyCounter {
198 #[cfg(feature = "spanned_tree")]
199 span: Default::default(),
200 }
201 }
202}