boseiju/ability_tree/
conditional.rs

1mod event_occured;
2mod number_of_resolution;
3mod object_is_of_kind;
4mod this_is_your_turn;
5
6pub use event_occured::ConditionEventOccured;
7pub use number_of_resolution::NumberOfResolutions;
8pub use object_is_of_kind::ConditionObjectMatchSpecifiers;
9pub use this_is_your_turn::ConditionThisIsYourTurn;
10
11use crate::ability_tree::AbilityTreeNode;
12use crate::ability_tree::MAX_CHILDREN_PER_NODE;
13
14/// A conditional clause allows ability to only trigger or happen when some other
15/// conditions are met.
16///
17/// There are two kind of contional, an "if" that requires that a condition is met,
18/// and an "unless" that requires that the condition has not been met.
19#[derive(serde::Serialize, serde::Deserialize)]
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum Conditional {
22    If(ConditionalIf),
23    Unless(ConditionalUnless),
24}
25
26impl AbilityTreeNode for Conditional {
27    fn node_id(&self) -> usize {
28        use idris::Idris;
29        crate::ability_tree::NodeKind::Conditional.id()
30    }
31
32    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
33        let mut children = arrayvec::ArrayVec::new_const();
34        match self {
35            Self::If(child) => children.push(child as &dyn AbilityTreeNode),
36            Self::Unless(child) => children.push(child as &dyn AbilityTreeNode),
37        }
38        children
39    }
40
41    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
42        use std::io::Write;
43        write!(out, "conditional:")?;
44        out.push_final_branch()?;
45        match self {
46            Self::If(child) => child.display(out)?,
47            Self::Unless(child) => child.display(out)?,
48        }
49        out.pop_branch();
50        Ok(())
51    }
52
53    fn node_tag(&self) -> &'static str {
54        "conditional"
55    }
56
57    #[cfg(feature = "spanned_tree")]
58    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
59        match self {
60            Self::If(child) => child.node_span(),
61            Self::Unless(child) => child.node_span(),
62        }
63    }
64}
65
66#[cfg(feature = "parser")]
67impl crate::utils::DummyInit for Conditional {
68    fn dummy_init() -> Self {
69        Self::If(crate::utils::dummy())
70    }
71}
72
73/// "If" variant of the [`Conditional`].
74#[derive(serde::Serialize, serde::Deserialize)]
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct ConditionalIf {
77    pub condition: Condition,
78    #[cfg(feature = "spanned_tree")]
79    pub span: crate::ability_tree::span::TreeSpan,
80}
81
82impl AbilityTreeNode for ConditionalIf {
83    fn node_id(&self) -> usize {
84        use idris::Idris;
85        crate::ability_tree::NodeKind::ConditionalIf.id()
86    }
87
88    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
89        let mut children = arrayvec::ArrayVec::new_const();
90        children.push(&self.condition as &dyn AbilityTreeNode);
91        children
92    }
93
94    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
95        use std::io::Write;
96        write!(out, "if:")?;
97        out.push_final_branch()?;
98        self.condition.display(out)?;
99        out.pop_branch();
100        Ok(())
101    }
102
103    fn node_tag(&self) -> &'static str {
104        "if condition"
105    }
106
107    #[cfg(feature = "spanned_tree")]
108    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
109        self.span
110    }
111}
112
113#[cfg(feature = "parser")]
114impl crate::utils::DummyInit for ConditionalIf {
115    fn dummy_init() -> Self {
116        Self {
117            condition: crate::utils::dummy(),
118            #[cfg(feature = "spanned_tree")]
119            span: Default::default(),
120        }
121    }
122}
123
124/// "Unless" variant of the [`Conditional`].
125#[derive(serde::Serialize, serde::Deserialize)]
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct ConditionalUnless {
128    pub condition: Condition,
129    #[cfg(feature = "spanned_tree")]
130    pub span: crate::ability_tree::span::TreeSpan,
131}
132
133impl AbilityTreeNode for ConditionalUnless {
134    fn node_id(&self) -> usize {
135        use idris::Idris;
136        crate::ability_tree::NodeKind::ConditionalUnless.id()
137    }
138
139    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
140        let mut children = arrayvec::ArrayVec::new_const();
141        children.push(&self.condition as &dyn AbilityTreeNode);
142        children
143    }
144
145    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
146        use std::io::Write;
147        write!(out, "unless:")?;
148        out.push_final_branch()?;
149        self.condition.display(out)?;
150        out.pop_branch();
151        Ok(())
152    }
153
154    fn node_tag(&self) -> &'static str {
155        "unless condition"
156    }
157
158    #[cfg(feature = "spanned_tree")]
159    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
160        self.span
161    }
162}
163
164#[cfg(feature = "parser")]
165impl crate::utils::DummyInit for ConditionalUnless {
166    fn dummy_init() -> Self {
167        Self {
168            condition: crate::utils::dummy(),
169            #[cfg(feature = "spanned_tree")]
170            span: Default::default(),
171        }
172    }
173}
174
175/// A condition regroups what can be used as conditions for conditinals.
176#[derive(serde::Serialize, serde::Deserialize)]
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub enum Condition {
179    EventOccured(ConditionEventOccured),
180    ObjectMatchSpecifiers(ConditionObjectMatchSpecifiers),
181    ThisIsYourTurn(ConditionThisIsYourTurn),
182}
183
184#[cfg(feature = "spanned_tree")]
185impl Condition {
186    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
187        match self {
188            Self::EventOccured(child) => child.span,
189            Self::ObjectMatchSpecifiers(child) => child.span,
190            Self::ThisIsYourTurn(child) => child.span,
191        }
192    }
193}
194
195impl AbilityTreeNode for Condition {
196    fn node_id(&self) -> usize {
197        use idris::Idris;
198        crate::ability_tree::NodeKind::Condition.id()
199    }
200
201    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
202        let mut children = arrayvec::ArrayVec::new_const();
203        match self {
204            Self::EventOccured(child) => children.push(child as &dyn AbilityTreeNode),
205            Self::ObjectMatchSpecifiers(child) => children.push(child as &dyn AbilityTreeNode),
206            Self::ThisIsYourTurn(child) => children.push(child as &dyn AbilityTreeNode),
207        }
208        children
209    }
210
211    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
212        use std::io::Write;
213        write!(out, "condition:")?;
214        out.push_final_branch()?;
215        match self {
216            Self::EventOccured(child) => child.display(out)?,
217            Self::ObjectMatchSpecifiers(child) => child.display(out)?,
218            Self::ThisIsYourTurn(child) => child.display(out)?,
219        }
220        out.pop_branch();
221        Ok(())
222    }
223
224    fn node_tag(&self) -> &'static str {
225        "condition"
226    }
227
228    #[cfg(feature = "spanned_tree")]
229    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
230        match self {
231            Self::EventOccured(child) => child.node_span(),
232            Self::ObjectMatchSpecifiers(child) => child.node_span(),
233            Self::ThisIsYourTurn(child) => child.node_span(),
234        }
235    }
236}
237
238#[cfg(feature = "parser")]
239impl crate::utils::DummyInit for Condition {
240    fn dummy_init() -> Self {
241        Self::ThisIsYourTurn(crate::utils::dummy())
242    }
243}