boseiju/ability_tree/object/
specified_object.rs

1use super::*;
2use crate::ability_tree::AbilityTreeNode;
3use crate::ability_tree::MAX_CHILDREN_PER_NODE;
4
5/// Fixme: doc
6/// Fixme: could we split this into an enum, having specified objects
7/// for all object kinds ? it would require more types, but would allow
8/// for more expressivness ?
9/// Fixme: at least we should have a specifier that acts as the main component ?
10/// "red card" -> card, "creatures you control" -> you control
11#[derive(serde::Serialize, serde::Deserialize)]
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct SpecifiedObject {
14    pub amount: CountSpecifier,
15    pub specifiers: Option<ObjectSpecifiers>,
16    #[cfg(feature = "spanned_tree")]
17    pub span: crate::ability_tree::span::TreeSpan,
18}
19
20impl AbilityTreeNode for SpecifiedObject {
21    fn node_id(&self) -> usize {
22        use idris::Idris;
23        crate::ability_tree::NodeKind::SpecifiedObject.id()
24    }
25
26    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
27        use crate::ability_tree::dummy_terminal::TreeNodeDummyTerminal;
28
29        let mut children = arrayvec::ArrayVec::new_const();
30        children.push(&self.amount as &dyn AbilityTreeNode);
31        match self.specifiers.as_ref() {
32            Some(specifiers) => children.push(specifiers as &dyn AbilityTreeNode),
33            None => children.push(TreeNodeDummyTerminal::none_node() as &dyn AbilityTreeNode),
34        }
35        children
36    }
37
38    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
39        use std::io::Write;
40        write!(out, "specified object:")?;
41        out.push_inter_branch()?;
42        write!(out, "amount:")?;
43        out.push_final_branch()?;
44        self.amount.display(out)?;
45        out.pop_branch();
46        out.next_final_branch()?;
47        write!(out, "specifier(s):")?;
48        out.push_final_branch()?;
49        match self.specifiers.as_ref() {
50            Some(specifiers) => specifiers.display(out)?,
51            None => write!(out, "none")?,
52        }
53        out.pop_branch();
54        out.pop_branch();
55        Ok(())
56    }
57
58    fn node_tag(&self) -> &'static str {
59        "specified object"
60    }
61
62    #[cfg(feature = "spanned_tree")]
63    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
64        self.span
65    }
66}