sieve/compiler/lexer/
mod.rs

1/*
2 * SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
3 *
4 * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
5 */
6
7pub mod string;
8pub mod tokenizer;
9pub mod word;
10
11use std::{borrow::Cow, fmt::Display};
12
13use self::word::Word;
14
15use super::{Number, Value};
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub(crate) enum Token {
19    CurlyOpen,
20    CurlyClose,
21    BracketOpen,
22    BracketClose,
23    ParenthesisOpen,
24    ParenthesisClose,
25    Comma,
26    Semicolon,
27    StringConstant(StringConstant),
28    StringVariable(Vec<u8>),
29    Number(usize),
30    Identifier(Word),
31    Tag(Word),
32    Unknown(String),
33    Colon,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub(crate) enum StringConstant {
38    String(String),
39    Number(Number),
40}
41
42impl StringConstant {
43    pub fn to_string(&self) -> Cow<str> {
44        match self {
45            StringConstant::String(s) => s.as_str().into(),
46            StringConstant::Number(n) => n.to_string().into(),
47        }
48    }
49
50    pub fn into_string(self) -> String {
51        match self {
52            StringConstant::String(s) => s,
53            StringConstant::Number(n) => n.to_string(),
54        }
55    }
56}
57
58impl From<StringConstant> for Value {
59    fn from(value: StringConstant) -> Self {
60        match value {
61            StringConstant::String(s) => Value::Text(s.into()),
62            StringConstant::Number(n) => Value::Number(n),
63        }
64    }
65}
66
67impl Display for Token {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        match self {
70            Token::CurlyOpen => f.write_str("{"),
71            Token::CurlyClose => f.write_str("}"),
72            Token::BracketOpen => f.write_str("["),
73            Token::BracketClose => f.write_str("]"),
74            Token::ParenthesisOpen => f.write_str("("),
75            Token::ParenthesisClose => f.write_str(")"),
76            Token::Comma => f.write_str(","),
77            Token::Semicolon => f.write_str(";"),
78            Token::Colon => f.write_str(":"),
79            Token::Number(n) => write!(f, "{n}"),
80            Token::Identifier(w) => w.fmt(f),
81            Token::Tag(t) => write!(f, ":{t}"),
82            Token::Unknown(s) => f.write_str(s),
83            Token::StringVariable(s) => f.write_str(&String::from_utf8_lossy(s)),
84            Token::StringConstant(c) => match c {
85                StringConstant::String(s) => f.write_str(s),
86                StringConstant::Number(n) => write!(f, "{n}"),
87            },
88        }
89    }
90}