boseiju/lexer/tokens/intermediates/
ambiguous_tokens.rs

1/// Tokens that can have different meanings depending on the context.
2///
3/// They are regrouped under a special "ambiguous" token kind,
4/// that we always parse first. This allows us to know that
5/// they will be parsed under this token kind, and not
6/// under and ambiguous token kind.
7#[derive(idris_derive::Idris)]
8#[derive(serde::Serialize, serde::Deserialize)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub enum AmbiguousToken {
11    /// Ambiguous between the player action and the creature action.
12    Attack {
13        #[cfg(feature = "spanned_tree")]
14        span: crate::ability_tree::span::TreeSpan,
15    },
16    /// Counter can either be a counter that we put on a permanent,
17    /// or the action to counter a spell.
18    Counter {
19        #[cfg(feature = "spanned_tree")]
20        span: crate::ability_tree::span::TreeSpan,
21    },
22    /// Exile can either refer to the exile zone, or to the action
23    /// of exiling something.
24    Exile {
25        #[cfg(feature = "spanned_tree")]
26        span: crate::ability_tree::span::TreeSpan,
27    },
28    /// Creatures can gain abilities
29    /// Players can gain life, gain control
30    Gain {
31        #[cfg(feature = "spanned_tree")]
32        span: crate::ability_tree::span::TreeSpan,
33    },
34    /// Type can be from a card
35    /// Or for mana type
36    Type {
37        #[cfg(feature = "spanned_tree")]
38        span: crate::ability_tree::span::TreeSpan,
39    },
40}
41
42#[cfg(feature = "spanned_tree")]
43impl AmbiguousToken {
44    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
45        match self {
46            Self::Attack { span } => *span,
47            Self::Counter { span } => *span,
48            Self::Exile { span } => *span,
49            Self::Gain { span } => *span,
50            Self::Type { span } => *span,
51        }
52    }
53}
54
55impl AmbiguousToken {
56    pub fn try_from_span(span: &crate::lexer::Span) -> Option<Self> {
57        match span.text {
58            "attack" | "attacks" | "attacked" => Some(Self::Attack {
59                #[cfg(feature = "spanned_tree")]
60                span: span.into(),
61            }),
62            "counter" | "counters" => Some(Self::Counter {
63                #[cfg(feature = "spanned_tree")]
64                span: span.into(),
65            }),
66            "exile" => Some(Self::Exile {
67                #[cfg(feature = "spanned_tree")]
68                span: span.into(),
69            }),
70            "gain" | "gains" | "gained" => Some(Self::Gain {
71                #[cfg(feature = "spanned_tree")]
72                span: span.into(),
73            }),
74            "type" => Some(Self::Gain {
75                #[cfg(feature = "spanned_tree")]
76                span: span.into(),
77            }),
78            _ => None,
79        }
80    }
81}