boseiju/lexer/tokens/intermediates/
number.rs

1#[derive(idris_derive::Idris)]
2#[derive(serde::Serialize, serde::Deserialize)]
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
4pub enum Number {
5    AnyNumber {
6        #[cfg(feature = "spanned_tree")]
7        span: crate::ability_tree::span::TreeSpan,
8    },
9    Number {
10        #[cfg(feature = "spanned_tree")]
11        span: crate::ability_tree::span::TreeSpan,
12        num: u32,
13    },
14    NumberOf {
15        #[cfg(feature = "spanned_tree")]
16        span: crate::ability_tree::span::TreeSpan,
17    },
18    OrMore {
19        #[cfg(feature = "spanned_tree")]
20        span: crate::ability_tree::span::TreeSpan,
21        num: u32,
22    },
23    ThatMany {
24        #[cfg(feature = "spanned_tree")]
25        span: crate::ability_tree::span::TreeSpan,
26    },
27    TwiceThatMany {
28        #[cfg(feature = "spanned_tree")]
29        span: crate::ability_tree::span::TreeSpan,
30    },
31    UpTo {
32        #[cfg(feature = "spanned_tree")]
33        span: crate::ability_tree::span::TreeSpan,
34        num: u32,
35    },
36    X {
37        #[cfg(feature = "spanned_tree")]
38        span: crate::ability_tree::span::TreeSpan,
39    },
40}
41
42#[cfg(feature = "spanned_tree")]
43impl Number {
44    pub fn span(&self) -> crate::ability_tree::span::TreeSpan {
45        match self {
46            Self::AnyNumber { span } => *span,
47            Self::Number { span, .. } => *span,
48            Self::NumberOf { span } => *span,
49            Self::OrMore { span, .. } => *span,
50            Self::ThatMany { span } => *span,
51            Self::TwiceThatMany { span } => *span,
52            Self::UpTo { span, .. } => *span,
53            Self::X { span } => *span,
54        }
55    }
56}
57
58impl Number {
59    pub fn try_from_span(span: &crate::lexer::Span) -> Option<Self> {
60        if let Some(num) = crate::utils::parse_num(span.text) {
61            Some(Self::Number {
62                num,
63                #[cfg(feature = "spanned_tree")]
64                span: span.into(),
65            })
66        } else if let Some(stripped) = span.text.strip_suffix(" or more") {
67            let num = crate::utils::parse_num(stripped)?;
68            Some(Self::OrMore {
69                num,
70                #[cfg(feature = "spanned_tree")]
71                span: span.into(),
72            })
73        } else if let Some(stripped) = span.text.strip_suffix(" or greater") {
74            let num = crate::utils::parse_num(stripped)?;
75            Some(Self::OrMore {
76                num,
77                #[cfg(feature = "spanned_tree")]
78                span: span.into(),
79            })
80        } else if let Some(stripped) = span.text.strip_prefix("up to ") {
81            let num = crate::utils::parse_num(stripped)?;
82            Some(Self::UpTo {
83                num,
84                #[cfg(feature = "spanned_tree")]
85                span: span.into(),
86            })
87        } else {
88            match span.text {
89                "x" => Some(Self::X {
90                    #[cfg(feature = "spanned_tree")]
91                    span: span.into(),
92                }),
93                "any number of" => Some(Self::AnyNumber {
94                    #[cfg(feature = "spanned_tree")]
95                    span: span.into(),
96                }),
97                "that many" | "that much" => Some(Self::ThatMany {
98                    #[cfg(feature = "spanned_tree")]
99                    span: span.into(),
100                }),
101                "number of" | "amount of" => Some(Self::NumberOf {
102                    #[cfg(feature = "spanned_tree")]
103                    span: span.into(),
104                }),
105                "twice that many" | "twice as much" => Some(Self::TwiceThatMany {
106                    #[cfg(feature = "spanned_tree")]
107                    span: span.into(),
108                }),
109                _ => None,
110            }
111        }
112    }
113}