boseiju/ability_tree/
number.rs

1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3use crate::ability_tree::MAX_NODE_DATA_SIZE;
4
5/// A number.
6///
7/// A number can be as simple as a literal number (e.g. "1", "two", "4") or
8/// a value that references some other objects (e.g. "ward X, where X is ...").
9///
10/// Number can also be "any number" where the player can choose whatever, or
11/// a reference to a previosuly mentionned number in the ability.
12#[derive(idris_derive::Idris)]
13#[derive(serde::Serialize, serde::Deserialize)]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum Number {
16    AnyNumber {
17        #[cfg(feature = "spanned_tree")]
18        span: crate::ability_tree::span::TreeSpan,
19    },
20    Number(FixedNumber),
21    OrMore(OrMoreNumber),
22    ThatMany {
23        #[cfg(feature = "spanned_tree")]
24        span: crate::ability_tree::span::TreeSpan,
25    },
26    UpTo(UpToNumber),
27    X(XNumber),
28}
29
30#[cfg(feature = "spanned_tree")]
31impl Number {
32    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
33        match self {
34            Self::AnyNumber { span } => *span,
35            Self::Number(number) => number.span,
36            Self::OrMore(number) => number.span,
37            Self::ThatMany { span } => *span,
38            Self::UpTo(number) => number.span,
39            Self::X(number) => number.span,
40        }
41    }
42}
43
44impl AbilityTreeNode for Number {
45    fn node_id(&self) -> usize {
46        use idris::Idris;
47        crate::ability_tree::NodeKind::NumberIdMarker.id()
48    }
49
50    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
51        use idris::Idris;
52        let mut children = arrayvec::ArrayVec::new_const();
53        match self {
54            Self::Number(child) => children.push(child as &dyn AbilityTreeNode),
55            Self::OrMore(child) => children.push(child as &dyn AbilityTreeNode),
56            Self::UpTo(child) => children.push(child as &dyn AbilityTreeNode),
57            Self::X(child) => children.push(child as &dyn AbilityTreeNode),
58            Self::AnyNumber { .. } | Self::ThatMany { .. } => {
59                children.push(crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::new(
60                    crate::ability_tree::NodeKind::Number(self.clone()).id(),
61                ) as &dyn AbilityTreeNode)
62            }
63        }
64        children
65    }
66
67    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
68        use std::io::Write;
69        match self {
70            Self::AnyNumber { .. } => write!(out, "any number")?,
71            Self::Number(number) => number.display(out)?,
72            Self::OrMore(number) => number.display(out)?,
73            Self::UpTo(number) => number.display(out)?,
74            Self::ThatMany { .. } => write!(out, "that many")?,
75            Self::X(number) => number.display(out)?,
76        }
77        Ok(())
78    }
79
80    fn node_tag(&self) -> &'static str {
81        "number"
82    }
83
84    #[cfg(feature = "spanned_tree")]
85    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
86        match self {
87            Self::AnyNumber { span } => *span,
88            Self::Number(child) => child.node_span(),
89            Self::OrMore(child) => child.node_span(),
90            Self::UpTo(child) => child.node_span(),
91            Self::ThatMany { span } => *span,
92            Self::X(child) => child.node_span(),
93        }
94    }
95}
96
97#[cfg(feature = "parser")]
98impl crate::utils::DummyInit for Number {
99    fn dummy_init() -> Self {
100        Self::Number(crate::utils::dummy())
101    }
102}
103
104/// A literal number in an ability, such as "1", "two", "10"
105#[derive(serde::Serialize, serde::Deserialize)]
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct FixedNumber {
108    pub number: u32,
109    #[cfg(feature = "spanned_tree")]
110    pub span: crate::ability_tree::span::TreeSpan,
111}
112
113impl AbilityTreeNode for FixedNumber {
114    fn node_id(&self) -> usize {
115        use idris::Idris;
116        crate::ability_tree::NodeKind::Number(Number::Number(self.clone())).id()
117    }
118
119    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
120        arrayvec::ArrayVec::new()
121    }
122
123    fn data(&self) -> arrayvec::ArrayVec<u8, MAX_NODE_DATA_SIZE> {
124        /* Fixme: that's terrible for the AI */
125        self.number.to_le_bytes().into_iter().collect()
126    }
127
128    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
129        use std::io::Write;
130        write!(out, "{}", self.number)
131    }
132
133    fn node_tag(&self) -> &'static str {
134        "fixed number"
135    }
136
137    #[cfg(feature = "spanned_tree")]
138    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
139        self.span
140    }
141}
142
143impl idris::Idris for FixedNumber {
144    const COUNT: usize = 1;
145    fn id(&self) -> usize {
146        0
147    }
148    fn name_from_id(_: usize) -> &'static str {
149        "number"
150    }
151}
152
153#[cfg(feature = "parser")]
154impl crate::utils::DummyInit for FixedNumber {
155    fn dummy_init() -> Self {
156        Self {
157            number: 0,
158            #[cfg(feature = "spanned_tree")]
159            span: Default::default(),
160        }
161    }
162}
163
164/// A number that can be anything after some minimum value: "one or more"
165#[derive(serde::Serialize, serde::Deserialize)]
166#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct OrMoreNumber {
168    pub minimum: u32,
169    #[cfg(feature = "spanned_tree")]
170    pub span: crate::ability_tree::span::TreeSpan,
171}
172
173impl AbilityTreeNode for OrMoreNumber {
174    fn node_id(&self) -> usize {
175        use idris::Idris;
176        crate::ability_tree::NodeKind::Number(Number::OrMore(self.clone())).id()
177    }
178
179    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
180        arrayvec::ArrayVec::new()
181    }
182
183    fn data(&self) -> arrayvec::ArrayVec<u8, MAX_NODE_DATA_SIZE> {
184        /* Fixme: that's terrible for the AI */
185        self.minimum.to_le_bytes().into_iter().collect()
186    }
187
188    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
189        use std::io::Write;
190        write!(out, "{} or more", self.minimum)
191    }
192
193    fn node_tag(&self) -> &'static str {
194        "or more number"
195    }
196
197    #[cfg(feature = "spanned_tree")]
198    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
199        self.span
200    }
201}
202
203impl idris::Idris for OrMoreNumber {
204    const COUNT: usize = 1;
205    fn id(&self) -> usize {
206        0
207    }
208    fn name_from_id(_: usize) -> &'static str {
209        "or more"
210    }
211}
212
213/// A number that can be anything after some minimum value: "one or more"
214#[derive(serde::Serialize, serde::Deserialize)]
215#[derive(Debug, Clone, PartialEq, Eq)]
216pub struct UpToNumber {
217    pub maximum: u32,
218    #[cfg(feature = "spanned_tree")]
219    pub span: crate::ability_tree::span::TreeSpan,
220}
221
222impl AbilityTreeNode for UpToNumber {
223    fn node_id(&self) -> usize {
224        use idris::Idris;
225        crate::ability_tree::NodeKind::Number(Number::UpTo(self.clone())).id()
226    }
227
228    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
229        arrayvec::ArrayVec::new()
230    }
231
232    fn data(&self) -> arrayvec::ArrayVec<u8, MAX_NODE_DATA_SIZE> {
233        /* Fixme: that's terrible for the AI */
234        self.maximum.to_le_bytes().into_iter().collect()
235    }
236
237    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
238        use std::io::Write;
239        write!(out, "up to {}", self.maximum)
240    }
241
242    fn node_tag(&self) -> &'static str {
243        "up to number"
244    }
245
246    #[cfg(feature = "spanned_tree")]
247    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
248        self.span
249    }
250}
251
252impl idris::Idris for UpToNumber {
253    const COUNT: usize = 1;
254    fn id(&self) -> usize {
255        0
256    }
257    fn name_from_id(_: usize) -> &'static str {
258        "or more"
259    }
260}
261
262/// An X number, where X is some other reference in the card:
263/// a mana cost, some value on cards, etc
264#[derive(serde::Serialize, serde::Deserialize)]
265#[derive(Debug, Clone, PartialEq, Eq)]
266pub struct XNumber {
267    pub x_definition: (), /* Fixme */
268    #[cfg(feature = "spanned_tree")]
269    pub span: crate::ability_tree::span::TreeSpan,
270}
271
272impl AbilityTreeNode for XNumber {
273    fn node_id(&self) -> usize {
274        use idris::Idris;
275        crate::ability_tree::NodeKind::Number(Number::X(self.clone())).id()
276    }
277
278    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
279        let children = arrayvec::ArrayVec::new_const();
280        /* Fixme: push x definition child node */
281        children
282    }
283
284    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
285        use std::io::Write;
286        write!(out, "x, where x is:")?;
287        out.push_final_branch()?;
288        /* Fixme: display x definition */
289        out.pop_branch();
290        Ok(())
291    }
292
293    fn node_tag(&self) -> &'static str {
294        "x number"
295    }
296
297    #[cfg(feature = "spanned_tree")]
298    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
299        self.span
300    }
301}
302
303impl idris::Idris for XNumber {
304    const COUNT: usize = 1;
305    fn id(&self) -> usize {
306        0
307    }
308    fn name_from_id(_: usize) -> &'static str {
309        "x"
310    }
311}