boseiju/ability_tree/object/
object_specifiers.rs

1mod cast_specifier;
2mod control_specifier;
3
4pub use cast_specifier::CastSpecifier;
5pub use control_specifier::ControlSpecifier;
6
7use crate::ability_tree::AbilityTreeNode;
8use crate::ability_tree::MAX_CHILDREN_PER_NODE;
9
10#[derive(serde::Serialize, serde::Deserialize)]
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum ObjectSpecifiers {
13    Single(ObjectSpecifier),
14    And(SpecifierAndList),
15    Or(SpecifierOrList),
16    OrOfAnd(SpecifierOrOfAndList),
17}
18
19impl ObjectSpecifiers {
20    /// Shortcut to build the "creature" object specifier.
21    pub fn creature(#[cfg(feature = "spanned_tree")] span: crate::ability_tree::span::TreeSpan) -> Self {
22        Self::Single(ObjectSpecifier::creature(
23            #[cfg(feature = "spanned_tree")]
24            span,
25        ))
26    }
27
28    #[cfg(feature = "spanned_tree")]
29    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
30        match self {
31            Self::Single(child) => child.node_span(),
32            Self::And(child) => child.span,
33            Self::Or(child) => child.span,
34            Self::OrOfAnd(child) => child.span,
35        }
36    }
37}
38
39impl ObjectSpecifiers {
40    pub fn add_factor_specifier(&self, factor_specifier: ObjectSpecifier) -> Self {
41        match self {
42            Self::Single(specifier) => Self::And(SpecifierAndList {
43                #[cfg(feature = "spanned_tree")]
44                span: self.node_span().merge(&factor_specifier.node_span()),
45                specifiers: {
46                    let mut specifiers = arrayvec::ArrayVec::new_const();
47                    specifiers.push(specifier.clone());
48                    specifiers.push(factor_specifier);
49                    specifiers
50                },
51            }),
52            Self::And(and) => Self::And(SpecifierAndList {
53                #[cfg(feature = "spanned_tree")]
54                span: and.span.merge(&factor_specifier.node_span()),
55                specifiers: {
56                    let mut and_specifiers = and.specifiers.clone();
57                    and_specifiers.push(factor_specifier);
58                    and_specifiers
59                },
60            }),
61            Self::Or(or) => Self::OrOfAnd({
62                let mut or_specifiers = arrayvec::ArrayVec::new_const();
63                for specifier in or.specifiers.iter() {
64                    let mut and_specifiers = arrayvec::ArrayVec::new_const();
65                    and_specifiers.push(specifier.clone());
66                    and_specifiers.push(factor_specifier.clone());
67                    or_specifiers.push(and_specifiers);
68                }
69                SpecifierOrOfAndList {
70                    specifiers: or_specifiers,
71                    #[cfg(feature = "spanned_tree")]
72                    span: or.span.merge(&factor_specifier.node_span()),
73                }
74            }),
75            Self::OrOfAnd(or_of_and) => Self::OrOfAnd({
76                let mut or_specifiers = or_of_and.specifiers.clone();
77                for and_specifiers in or_specifiers.iter_mut() {
78                    and_specifiers.push(factor_specifier.clone());
79                }
80                SpecifierOrOfAndList {
81                    specifiers: or_specifiers,
82                    #[cfg(feature = "spanned_tree")]
83                    span: or_of_and.span.merge(&factor_specifier.node_span()),
84                }
85            }),
86        }
87    }
88}
89
90impl crate::ability_tree::AbilityTreeNode for ObjectSpecifiers {
91    fn node_id(&self) -> usize {
92        use idris::Idris;
93        crate::ability_tree::NodeKind::ObjectSpecifiers.id()
94    }
95
96    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
97        let mut children = arrayvec::ArrayVec::new_const();
98        match self {
99            Self::Single(child) => children.push(child as &dyn AbilityTreeNode),
100            Self::And(child) => children.push(child as &dyn AbilityTreeNode),
101            Self::Or(child) => children.push(child as &dyn AbilityTreeNode),
102            Self::OrOfAnd(child) => children.push(child as &dyn AbilityTreeNode),
103        }
104        children
105    }
106
107    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
108        use std::io::Write;
109        write!(out, "object specifiers:")?;
110        out.push_final_branch()?;
111        match self {
112            Self::Single(child) => child.display(out)?,
113            Self::And(child) => child.display(out)?,
114            Self::Or(child) => child.display(out)?,
115            Self::OrOfAnd(child) => child.display(out)?,
116        }
117        out.pop_branch();
118        Ok(())
119    }
120
121    fn node_tag(&self) -> &'static str {
122        "object specifiers"
123    }
124
125    #[cfg(feature = "spanned_tree")]
126    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
127        match self {
128            Self::Single(child) => child.node_span(),
129            Self::And(child) => child.node_span(),
130            Self::Or(child) => child.node_span(),
131            Self::OrOfAnd(child) => child.node_span(),
132        }
133    }
134}
135
136#[cfg(feature = "parser")]
137impl crate::utils::DummyInit for ObjectSpecifiers {
138    fn dummy_init() -> Self {
139        Self::Single(crate::utils::dummy())
140    }
141}
142
143/// A list of object specifiers, grouped with a logical AND.
144///
145/// It means that for an object to match these specifiers,
146/// it must match all of them.
147#[derive(serde::Serialize, serde::Deserialize)]
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct SpecifierAndList {
150    pub specifiers: arrayvec::ArrayVec<ObjectSpecifier, MAX_CHILDREN_PER_NODE>,
151    #[cfg(feature = "spanned_tree")]
152    pub span: crate::ability_tree::span::TreeSpan,
153}
154
155impl AbilityTreeNode for SpecifierAndList {
156    fn node_id(&self) -> usize {
157        use idris::Idris;
158        crate::ability_tree::NodeKind::SpecifierAndList.id()
159    }
160
161    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
162        let mut children = arrayvec::ArrayVec::new_const();
163        for specifier in self.specifiers.iter() {
164            children.push(specifier 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, "specifier and list:")?;
172        for (i, specifier) in self.specifiers.iter().enumerate() {
173            if i == self.specifiers.len() - 1 {
174                out.push_final_branch()?;
175            } else {
176                out.push_inter_branch()?;
177            }
178            specifier.display(out)?;
179            out.pop_branch();
180        }
181        Ok(())
182    }
183
184    fn node_tag(&self) -> &'static str {
185        "specifiers and list"
186    }
187
188    #[cfg(feature = "spanned_tree")]
189    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
190        self.span
191    }
192}
193
194#[cfg(feature = "parser")]
195impl crate::utils::DummyInit for SpecifierAndList {
196    fn dummy_init() -> Self {
197        Self {
198            specifiers: arrayvec::ArrayVec::new_const(),
199            #[cfg(feature = "spanned_tree")]
200            span: Default::default(),
201        }
202    }
203}
204
205/// A list of object specifiers, grouped with a logical OR.
206///
207/// It means that for an object to match these specifiers,
208/// it must match any one specifier in the list.
209#[derive(serde::Serialize, serde::Deserialize)]
210#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct SpecifierOrList {
212    pub specifiers: arrayvec::ArrayVec<ObjectSpecifier, MAX_CHILDREN_PER_NODE>,
213    #[cfg(feature = "spanned_tree")]
214    pub span: crate::ability_tree::span::TreeSpan,
215}
216
217impl SpecifierOrList {
218    pub fn add_factor_specifier(&self, factor_specifier: ObjectSpecifier) -> SpecifierOrOfAndList {
219        let mut or_specifiers = arrayvec::ArrayVec::new_const();
220        for prev_specifier in self.specifiers.iter() {
221            let mut and_specifiers = arrayvec::ArrayVec::new_const();
222            and_specifiers.push(prev_specifier.clone());
223            and_specifiers.push(factor_specifier.clone());
224            or_specifiers.push(and_specifiers);
225        }
226        SpecifierOrOfAndList {
227            specifiers: or_specifiers,
228            #[cfg(feature = "spanned_tree")]
229            span: self.span.merge(&factor_specifier.node_span()),
230        }
231    }
232
233    #[cfg(feature = "spanned_tree")]
234    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
235        self.span
236    }
237}
238
239impl AbilityTreeNode for SpecifierOrList {
240    fn node_id(&self) -> usize {
241        use idris::Idris;
242        crate::ability_tree::NodeKind::SpecifierOrList.id()
243    }
244
245    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
246        let mut children = arrayvec::ArrayVec::new_const();
247        for specifier in self.specifiers.iter() {
248            children.push(specifier as &dyn AbilityTreeNode);
249        }
250        children
251    }
252
253    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
254        use std::io::Write;
255        write!(out, "specifier or list:")?;
256        for (i, specifier) in self.specifiers.iter().enumerate() {
257            if i == self.specifiers.len() - 1 {
258                out.push_final_branch()?;
259            } else {
260                out.push_inter_branch()?;
261            }
262            specifier.display(out)?;
263            out.pop_branch();
264        }
265        Ok(())
266    }
267
268    fn node_tag(&self) -> &'static str {
269        "specifiers or list"
270    }
271
272    #[cfg(feature = "spanned_tree")]
273    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
274        self.span
275    }
276}
277
278#[cfg(feature = "parser")]
279impl crate::utils::DummyInit for SpecifierOrList {
280    fn dummy_init() -> Self {
281        Self {
282            specifiers: arrayvec::ArrayVec::new_const(),
283            #[cfg(feature = "spanned_tree")]
284            span: Default::default(),
285        }
286    }
287}
288
289const OR_OF_AND_LIST_OUTER_ARRAY_LENGTH: usize = 3;
290const OR_OF_AND_LIST_INNER_ARRAY_LENGTH: usize = MAX_CHILDREN_PER_NODE / OR_OF_AND_LIST_OUTER_ARRAY_LENGTH;
291
292/// A list of list of object specifiers, where the outer list is grouped
293/// with a logical OR, and the inner list is grouped with a logical AND.
294///
295/// It means that for an object to match these specifiers,
296/// it must match all the specifiers of any one of the sublists.
297///
298/// This is required since sometimes, there are specifiers that applies to
299/// OR lists: "basic plains or forest" means "(basic AND plains) OR (basic AND forest)".
300///
301/// This structure represent properly this case.
302#[derive(serde::Serialize, serde::Deserialize)]
303#[derive(Debug, Clone, PartialEq, Eq)]
304pub struct SpecifierOrOfAndList {
305    pub specifiers: arrayvec::ArrayVec<
306        arrayvec::ArrayVec<ObjectSpecifier, OR_OF_AND_LIST_INNER_ARRAY_LENGTH>,
307        OR_OF_AND_LIST_OUTER_ARRAY_LENGTH,
308    >,
309    #[cfg(feature = "spanned_tree")]
310    pub span: crate::ability_tree::span::TreeSpan,
311}
312
313impl AbilityTreeNode for SpecifierOrOfAndList {
314    fn node_id(&self) -> usize {
315        use idris::Idris;
316        crate::ability_tree::NodeKind::SpecifierOrOfAndList.id()
317    }
318
319    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
320        /* We want to flatten our list of list will keeping semantics of which specifiers are the ors and ands.
321         * To do this, we use the position of the nodes in the array, so the layout will always be:
322         * [[s1, s2, s3, s4], [s1, s2, s3, s4], [s1, s2, s3, s4]]
323         * with the specifiers maybe being the empty node.
324         */
325        let mut children = arrayvec::ArrayVec::new_const();
326        for and_specifier in self.specifiers.iter() {
327            /* Create an iterator of dummy empty nodes as ability tree */
328            let dummy_nodes = std::iter::repeat(crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::empty_node());
329            let dummy_nodes = dummy_nodes.map(|c| c as &dyn AbilityTreeNode);
330
331            /* Iterate over the specifiers, filled up with dummy nodes if there are less than OR_OF_AND_LIST_INNER_ARRAY_LENGTH specifiers */
332            for specifier in and_specifier
333                .iter()
334                .map(|s| s as &dyn AbilityTreeNode)
335                .chain(dummy_nodes)
336                .take(OR_OF_AND_LIST_INNER_ARRAY_LENGTH)
337            {
338                children.push(specifier as &dyn AbilityTreeNode);
339            }
340        }
341        children
342    }
343
344    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
345        use std::io::Write;
346        write!(out, "specifier or list:")?;
347        for (i, and_specifier) in self.specifiers.iter().enumerate() {
348            if i == self.specifiers.len() - 1 {
349                out.push_final_branch()?;
350            } else {
351                out.push_inter_branch()?;
352            }
353            write!(out, "specifier and list:")?;
354            for (j, specifier) in and_specifier.iter().enumerate() {
355                if j == self.specifiers.len() - 1 {
356                    out.push_final_branch()?;
357                } else {
358                    out.push_inter_branch()?;
359                }
360                specifier.display(out)?;
361                out.pop_branch();
362            }
363            out.pop_branch();
364        }
365        Ok(())
366    }
367
368    fn node_tag(&self) -> &'static str {
369        "specifiers or of and list"
370    }
371
372    #[cfg(feature = "spanned_tree")]
373    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
374        self.span
375    }
376}
377
378#[cfg(feature = "parser")]
379impl crate::utils::DummyInit for SpecifierOrOfAndList {
380    fn dummy_init() -> Self {
381        Self {
382            specifiers: arrayvec::ArrayVec::new_const(),
383            #[cfg(feature = "spanned_tree")]
384            span: Default::default(),
385        }
386    }
387}
388
389/// Fixme: doc
390#[derive(serde::Serialize, serde::Deserialize)]
391#[derive(Debug, Clone, PartialEq, Eq)]
392pub enum ObjectSpecifier {
393    Another(AnotherObjectSpecifier),
394    Cast(CastSpecifier),
395    Color(crate::ability_tree::terminals::Color),
396    Control(ControlSpecifier),
397    Kind(crate::ability_tree::object::ObjectKind),
398    NotOfAKind(crate::ability_tree::object::ObjectKind),
399    NotPreviouslySelected(NotPreviouslySelectedObjectSpecifier),
400}
401
402impl ObjectSpecifier {
403    /// Sortcut to create a kind: creature object specifier
404    pub fn creature(#[cfg(feature = "spanned_tree")] span: crate::ability_tree::span::TreeSpan) -> Self {
405        ObjectSpecifier::Kind(crate::ability_tree::object::ObjectKind::CardType(
406            crate::ability_tree::object::CardType {
407                card_type: mtg_data::CardType::Creature,
408                #[cfg(feature = "spanned_tree")]
409                span,
410            },
411        ))
412    }
413}
414
415impl AbilityTreeNode for ObjectSpecifier {
416    fn node_id(&self) -> usize {
417        use idris::Idris;
418        crate::ability_tree::NodeKind::ObjectSpecifier.id()
419    }
420
421    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
422        let mut children = arrayvec::ArrayVec::new_const();
423        match self {
424            Self::Another(child) => children.push(child as &dyn AbilityTreeNode),
425            Self::Cast(child) => children.push(child as &dyn AbilityTreeNode),
426            Self::Control(child) => children.push(child as &dyn AbilityTreeNode),
427            Self::Color(child) => children.push(child as &dyn AbilityTreeNode),
428            Self::Kind(child) => children.push(child as &dyn AbilityTreeNode),
429            Self::NotOfAKind(child) => children.push(child as &dyn AbilityTreeNode),
430            Self::NotPreviouslySelected(child) => children.push(child as &dyn AbilityTreeNode),
431        }
432        children
433    }
434
435    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
436        use std::io::Write;
437        match self {
438            ObjectSpecifier::Another(_) => write!(out, "not self specifier:")?,
439            ObjectSpecifier::Cast(_) => write!(out, "cast specifier:")?,
440            ObjectSpecifier::Color(_) => write!(out, "color specifier:")?,
441            ObjectSpecifier::Control(_) => write!(out, "control specifier:")?,
442            ObjectSpecifier::Kind(_) => write!(out, "kind specifier:")?,
443            ObjectSpecifier::NotOfAKind(_) => write!(out, "not of a kind specifier:")?,
444            ObjectSpecifier::NotPreviouslySelected(_) => write!(out, "not previously selected:")?,
445        }
446        out.push_final_branch()?;
447        match self {
448            ObjectSpecifier::Another(another) => another.display(out)?,
449            ObjectSpecifier::Cast(cast) => cast.display(out)?,
450            ObjectSpecifier::Color(color) => color.display(out)?,
451            ObjectSpecifier::Control(control) => control.display(out)?,
452            ObjectSpecifier::Kind(object) => object.display(out)?,
453            ObjectSpecifier::NotOfAKind(object) => object.display(out)?,
454            ObjectSpecifier::NotPreviouslySelected(another) => another.display(out)?,
455        }
456        out.pop_branch();
457        Ok(())
458    }
459
460    fn node_tag(&self) -> &'static str {
461        "object specifier"
462    }
463
464    #[cfg(feature = "spanned_tree")]
465    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
466        match self {
467            Self::Another(child) => child.node_span(),
468            Self::Cast(child) => child.node_span(),
469            Self::Color(child) => child.node_span(),
470            Self::Control(child) => child.node_span(),
471            Self::Kind(child) => child.node_span(),
472            Self::NotOfAKind(child) => child.node_span(),
473            Self::NotPreviouslySelected(child) => child.node_span(),
474        }
475    }
476}
477
478#[cfg(feature = "parser")]
479impl crate::utils::DummyInit for ObjectSpecifier {
480    fn dummy_init() -> Self {
481        Self::Color(crate::utils::dummy())
482    }
483}
484
485/// Marker struct for the special object specifier "another",
486/// which means "any that is not myself".
487#[derive(serde::Serialize, serde::Deserialize)]
488#[derive(Debug, Clone, PartialEq, Eq)]
489pub struct AnotherObjectSpecifier {
490    #[cfg(feature = "spanned_tree")]
491    pub span: crate::ability_tree::span::TreeSpan,
492}
493
494impl AbilityTreeNode for AnotherObjectSpecifier {
495    fn node_id(&self) -> usize {
496        use crate::ability_tree::tree_node::TerminalNodeKind;
497        use idris::Idris;
498
499        crate::ability_tree::NodeKind::Terminal(TerminalNodeKind::AnotherObjectSpecifier).id()
500    }
501
502    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
503        arrayvec::ArrayVec::new()
504    }
505
506    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
507        use std::io::Write;
508        write!(out, "{self}")
509    }
510
511    fn node_tag(&self) -> &'static str {
512        "another object specifier"
513    }
514
515    #[cfg(feature = "spanned_tree")]
516    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
517        self.span
518    }
519}
520
521impl std::fmt::Display for AnotherObjectSpecifier {
522    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523        write!(f, "others")
524    }
525}
526
527/// Marker struct for the special object specifier "other target",
528/// which means "any target that was not already selected"
529#[derive(serde::Serialize, serde::Deserialize)]
530#[derive(Debug, Clone, PartialEq, Eq)]
531pub struct NotPreviouslySelectedObjectSpecifier {
532    #[cfg(feature = "spanned_tree")]
533    pub span: crate::ability_tree::span::TreeSpan,
534}
535
536impl AbilityTreeNode for NotPreviouslySelectedObjectSpecifier {
537    fn node_id(&self) -> usize {
538        use crate::ability_tree::tree_node::TerminalNodeKind;
539        use idris::Idris;
540
541        crate::ability_tree::NodeKind::Terminal(TerminalNodeKind::NotPreviouslySelectedObjectSpecifier).id()
542    }
543
544    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
545        arrayvec::ArrayVec::new()
546    }
547
548    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
549        use std::io::Write;
550        write!(out, "{self}")
551    }
552
553    fn node_tag(&self) -> &'static str {
554        "not previously selected specifier"
555    }
556
557    #[cfg(feature = "spanned_tree")]
558    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
559        self.span
560    }
561}
562
563impl std::fmt::Display for NotPreviouslySelectedObjectSpecifier {
564    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
565        write!(f, "not previously selected")
566    }
567}