boseiju/ability_tree/imperative/
exile_imperative.rs

1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3
4/// Fixme: doc
5#[derive(serde::Serialize, serde::Deserialize)]
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ExileImperative {
8    pub object: crate::ability_tree::object::ObjectReference,
9    pub follow_up: Option<ExileFollowUp>,
10    #[cfg(feature = "spanned_tree")]
11    pub span: crate::ability_tree::span::TreeSpan,
12}
13
14impl crate::ability_tree::AbilityTreeNode for ExileImperative {
15    fn node_id(&self) -> usize {
16        use idris::Idris;
17        crate::ability_tree::NodeKind::DestroyImperative.id()
18    }
19
20    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
21        let mut children = arrayvec::ArrayVec::new_const();
22        children.push(&self.object as &dyn AbilityTreeNode);
23        match self.follow_up.as_ref() {
24            Some(follow_up) => children.push(follow_up as &dyn AbilityTreeNode),
25            None => {
26                let dummy = crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::none_node();
27                children.push(dummy as &dyn AbilityTreeNode)
28            }
29        }
30        children
31    }
32
33    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
34        use std::io::Write;
35        write!(out, "exile:")?;
36        out.push_inter_branch()?;
37        write!(out, "object:")?;
38        out.push_final_branch()?;
39        self.object.display(out)?;
40        out.pop_branch();
41        out.next_inter_branch()?;
42        match self.follow_up.as_ref() {
43            Some(follow_up) => {
44                write!(out, "and then:")?;
45                out.push_final_branch()?;
46                follow_up.display(out)?;
47                out.pop_branch();
48            }
49            None => write!(out, "and then: that's it")?,
50        }
51        out.pop_branch();
52        Ok(())
53    }
54
55    fn node_tag(&self) -> &'static str {
56        "exile imperative"
57    }
58
59    #[cfg(feature = "spanned_tree")]
60    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
61        self.span
62    }
63}
64
65#[cfg(feature = "parser")]
66impl crate::utils::DummyInit for ExileImperative {
67    fn dummy_init() -> Self {
68        Self {
69            object: crate::utils::dummy(),
70            follow_up: crate::utils::dummy(),
71            #[cfg(feature = "spanned_tree")]
72            span: Default::default(),
73        }
74    }
75}
76
77/// List of things that can happen after exiling stuff
78#[derive(serde::Serialize, serde::Deserialize)]
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub enum ExileFollowUp {
81    ReturnIt(ExileFollowUpReturn),
82}
83
84#[cfg(feature = "spanned_tree")]
85impl ExileFollowUp {
86    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
87        match self {
88            Self::ReturnIt(child) => child.span,
89        }
90    }
91}
92
93impl AbilityTreeNode for ExileFollowUp {
94    fn node_id(&self) -> usize {
95        use idris::Idris;
96        crate::ability_tree::NodeKind::ExileFollowUp.id()
97    }
98
99    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
100        let mut children = arrayvec::ArrayVec::new_const();
101        match self {
102            Self::ReturnIt(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, "exile follow up:")?;
110        out.push_final_branch()?;
111        match self {
112            Self::ReturnIt(child) => child.display(out)?,
113        }
114        out.pop_branch();
115        Ok(())
116    }
117
118    fn node_tag(&self) -> &'static str {
119        "exile follow up"
120    }
121
122    #[cfg(feature = "spanned_tree")]
123    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
124        match self {
125            Self::ReturnIt(child) => child.node_span(),
126        }
127    }
128}
129
130#[cfg(feature = "parser")]
131impl crate::utils::DummyInit for ExileFollowUp {
132    fn dummy_init() -> Self {
133        Self::ReturnIt(crate::utils::dummy())
134    }
135}
136
137/// Follow up to return an object after exiling it.
138#[derive(serde::Serialize, serde::Deserialize)]
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct ExileFollowUpReturn {
141    pub return_imperative: crate::ability_tree::imperative::ReturnImperative,
142    pub at: Option<crate::ability_tree::time::Instant>,
143    #[cfg(feature = "spanned_tree")]
144    pub span: crate::ability_tree::span::TreeSpan,
145}
146
147impl AbilityTreeNode for ExileFollowUpReturn {
148    fn node_id(&self) -> usize {
149        use idris::Idris;
150        crate::ability_tree::NodeKind::ExileFollowUpReturn.id()
151    }
152
153    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
154        let mut children = arrayvec::ArrayVec::new_const();
155        children.push(&self.return_imperative as &dyn AbilityTreeNode);
156        match self.at.as_ref() {
157            Some(at) => children.push(at as &dyn AbilityTreeNode),
158            None => {
159                let dummy = crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal::none_node();
160                children.push(dummy as &dyn AbilityTreeNode)
161            }
162        }
163        children
164    }
165
166    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
167        use std::io::Write;
168        write!(out, "return:")?;
169        out.push_inter_branch()?;
170        write!(out, "return imperative:")?;
171        out.push_final_branch()?;
172        self.return_imperative.display(out)?;
173        out.pop_branch();
174        out.next_final_branch()?;
175        write!(out, "at:")?;
176        out.push_final_branch()?;
177        match self.at.as_ref() {
178            Some(at) => at.display(out)?,
179            None => write!(out, "immediatly")?,
180        }
181        out.pop_branch();
182        out.pop_branch();
183        Ok(())
184    }
185
186    fn node_tag(&self) -> &'static str {
187        "exile follow up: return"
188    }
189
190    #[cfg(feature = "spanned_tree")]
191    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
192        self.span
193    }
194}
195
196#[cfg(feature = "parser")]
197impl crate::utils::DummyInit for ExileFollowUpReturn {
198    fn dummy_init() -> Self {
199        Self {
200            return_imperative: crate::utils::dummy(),
201            at: crate::utils::dummy(),
202            #[cfg(feature = "spanned_tree")]
203            span: Default::default(),
204        }
205    }
206}