boseiju/ability_tree/object/
self_referencing.rs

1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3use crate::lexer::IntoToken;
4
5/// The self referencing struct is a special kind of object specifier
6/// that references the objects that carries the ability.
7///
8/// For instance, in the ability text "when this creature enters, ...",
9/// "this creature" is a self referencing keyword.
10///
11/// Prior to the Foundation (FDN) set, self referencing was done by mentionning the
12/// name of the card, either the full name or without the epiphet.
13///
14/// Since FDN, self referencing can be done through "this card / creature / etc".
15#[derive(serde::Serialize, serde::Deserialize)]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
17pub struct SelfReferencingObject {
18    #[cfg(feature = "spanned_tree")]
19    pub span: crate::ability_tree::span::TreeSpan,
20}
21
22impl AbilityTreeNode for SelfReferencingObject {
23    fn node_id(&self) -> usize {
24        use crate::ability_tree::tree_node::TerminalNodeKind;
25        use idris::Idris;
26        crate::ability_tree::NodeKind::Terminal(TerminalNodeKind::SelfReferencing).id()
27    }
28
29    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
30        arrayvec::ArrayVec::new()
31    }
32
33    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
34        use std::io::Write;
35        write!(out, "{self}")
36    }
37
38    fn node_tag(&self) -> &'static str {
39        "self referencing"
40    }
41
42    #[cfg(feature = "spanned_tree")]
43    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
44        self.span
45    }
46}
47
48impl std::fmt::Display for SelfReferencingObject {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        write!(f, "self referencing (~)")
51    }
52}
53
54impl IntoToken for SelfReferencingObject {
55    #[cfg(feature = "lexer")]
56    fn try_from_span(span: &crate::lexer::Span) -> Option<Self> {
57        match span.text {
58            "this creature" => Some(SelfReferencingObject {
59                #[cfg(feature = "spanned_tree")]
60                span: span.into(),
61            }),
62            "this spell" => Some(SelfReferencingObject {
63                #[cfg(feature = "spanned_tree")]
64                span: span.into(),
65            }),
66            "this card" => Some(SelfReferencingObject {
67                #[cfg(feature = "spanned_tree")]
68                span: span.into(),
69            }),
70            "this token" => Some(SelfReferencingObject {
71                #[cfg(feature = "spanned_tree")]
72                span: span.into(),
73            }),
74            "~" => Some(SelfReferencingObject {
75                #[cfg(feature = "spanned_tree")]
76                span: span.into(),
77            }),
78            _ => None,
79        }
80    }
81}
82
83#[cfg(feature = "parser")]
84impl crate::utils::DummyInit for SelfReferencingObject {
85    fn dummy_init() -> Self {
86        Self {
87            #[cfg(feature = "spanned_tree")]
88            span: Default::default(),
89        }
90    }
91}