boseiju/ability_tree/imperative/
create_token_imperative.rs

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