boseiju/ability_tree/
zone.rs

1mod owned_zone;
2mod zone;
3
4use idris::Idris;
5pub use owned_zone::OwnedZone;
6pub use zone::OwnableZone;
7
8use crate::ability_tree::AbilityTreeNode;
9use crate::ability_tree::MAX_CHILDREN_PER_NODE;
10
11/// Reference to a "zone", which are the various places of the game.
12///
13/// Some references are to zone that are common to all players: exile, the battlefield, etc.
14/// Otherwise, there are "owned zones" such as the players hand, libraries, etc.
15#[derive(idris_derive::Idris)]
16#[derive(serde::Serialize, serde::Deserialize)]
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
18pub enum ZoneReference {
19    Anywhere {
20        #[cfg(feature = "spanned_tree")]
21        span: crate::ability_tree::span::TreeSpan,
22    },
23    Exile {
24        #[cfg(feature = "spanned_tree")]
25        span: crate::ability_tree::span::TreeSpan,
26    },
27    OwnedZone(OwnedZone),
28    TheBattlefield {
29        #[cfg(feature = "spanned_tree")]
30        span: crate::ability_tree::span::TreeSpan,
31    },
32}
33
34impl AbilityTreeNode for ZoneReference {
35    fn node_id(&self) -> usize {
36        use idris::Idris;
37        crate::ability_tree::NodeKind::ZoneReferenceIdMarker.id()
38    }
39
40    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
41        let mut children = arrayvec::ArrayVec::new_const();
42        match self {
43            Self::OwnedZone(child) => children.push(child as &dyn AbilityTreeNode),
44            Self::Anywhere { .. } | Self::Exile { .. } | Self::TheBattlefield { .. } => {
45                children.push(crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::new(
46                    crate::ability_tree::NodeKind::ZoneReference(self.clone()).id(),
47                ) as &dyn AbilityTreeNode)
48            }
49        }
50        children
51    }
52
53    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
54        use std::io::Write;
55        match self {
56            Self::Anywhere { .. } => write!(out, "anywhere"),
57            Self::Exile { .. } => write!(out, "exile"),
58            Self::OwnedZone(owned) => owned.display(out),
59            Self::TheBattlefield { .. } => write!(out, "the battlefield"),
60        }
61    }
62
63    fn node_tag(&self) -> &'static str {
64        "zone reference type"
65    }
66
67    #[cfg(feature = "spanned_tree")]
68    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
69        match self {
70            Self::Anywhere { span } => *span,
71            Self::Exile { span } => *span,
72            Self::OwnedZone(child) => child.node_span(),
73            Self::TheBattlefield { span } => *span,
74        }
75    }
76}
77
78#[cfg(feature = "parser")]
79impl crate::utils::DummyInit for ZoneReference {
80    fn dummy_init() -> Self {
81        Self::Anywhere {
82            #[cfg(feature = "spanned_tree")]
83            span: Default::default(),
84        }
85    }
86}