1use std::{fmt::Display, ops::RangeBounds};
2
3#[derive(Debug, PartialEq, Default, Copy, Clone)]
4pub struct Data<'a> {
5 pub start: usize,
6 pub end: usize,
7 pub value: &'a str,
8}
9
10impl<'a> Data<'a> {
11 pub fn new(start: usize, end: usize, value: &'a str) -> Data<'a> {
12 Data { start, end, value }
13 }
14}
15
16impl<'a> RangeBounds<usize> for &Data<'a> {
17 fn start_bound(&self) -> std::ops::Bound<&usize> {
18 std::ops::Bound::Included(&self.start)
19 }
20
21 fn end_bound(&self) -> std::ops::Bound<&usize> {
22 std::ops::Bound::Excluded(&self.end)
23 }
24}
25
26#[derive(Debug, PartialEq, Clone)]
27pub enum Token<'a> {
28 Illegal(Data<'a>),
29 Eof(Data<'a>),
30 Colon(Data<'a>),
31 Semicolon(Data<'a>),
32 Word(Data<'a>),
33 Number(Data<'a>),
34 Comment(Data<'a>),
35 StackComment(Data<'a>),
36}
37
38impl<'a> Token<'a> {
39 pub fn get_data(&self) -> &Data<'a> {
40 match self {
41 Token::Illegal(dat) => dat,
42 Token::Eof(dat) => dat,
43 Token::Colon(dat) => dat,
44 Token::Semicolon(dat) => dat,
45 Token::Word(dat) => dat,
46 Token::Number(dat) => dat,
47 Token::Comment(dat) => dat,
48 Token::StackComment(dat) => dat,
49 }
50 }
51}
52
53impl<'a> Display for Token<'a> {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 match self {
56 Token::Illegal(_) => write!(f, ""),
57 Token::Eof(_) => write!(f, "\0"),
58 Token::Word(value)
59 | Token::Number(value)
60 | Token::StackComment(value)
61 | Token::Comment(value) => write!(f, "{value:?}"),
62 Token::Colon(_) => write!(f, ":"),
63 Token::Semicolon(_) => write!(f, ";"),
64 }
65 }
66}
67
68impl<'a> From<Data<'a>> for Token<'a> {
69 fn from(value: Data<'a>) -> Self {
70 match value.value {
71 ";" => Self::Semicolon(value),
72 ":" => Self::Colon(value),
73 "\0" => Self::Eof(value),
74 _ => {
75 if value.value.chars().all(|b| b.is_ascii_digit()) {
76 Self::Number(value)
77 } else {
78 Self::Word(value)
79 }
80 }
81 }
82 }
83}