token_lists/
lib.rs

1#![deny(missing_docs)]
2/*!
3This crate contains a minimal form of s-expressions, which will be called token lists.
4
5Every element, called token, is either a symbol or a list of multiple tokens.
6
7Other libraries like the token parser can be used to parse tokens.
8**/
9
10/// Represents the token lists.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub enum Token {
13    /// A symbol token represented by its name.
14    Symbol(Box<str>),
15    /// A list token containing other tokens.
16    List(Vec<Token>),
17}
18
19use Token::*;
20
21impl Token {
22    /// If the token is a `Symbol`, returns an `Option`, containing the symbol name.
23    /// Else returns `None`.
24    pub fn symbol(self) -> Option<Box<str>> {
25        match self {
26            Symbol(string) => Some(string),
27            List(_) => None,
28        }
29    }
30
31    /// Same as `fn symbol`, but returns a ref.
32    pub fn symbol_ref(&self) -> Option<&str> {
33        match self {
34            Symbol(string) => Some(string),
35            List(_) => None,
36        }
37    }
38
39    /// If the token is a `List`, returns an `Option`, containing the elements.
40    /// Else returns `None`.
41    pub fn list(self) -> Option<Vec<Self>> {
42        match self {
43            Symbol(_) => None,
44            List(tokens) => Some(tokens),
45        }
46    }
47
48    /// Same as `fn list`, but returns a ref.
49    pub fn list_ref(&self) -> Option<&Vec<Self>> {
50        match self {
51            Symbol(_) => None,
52            List(tokens) => Some(tokens),
53        }
54    }
55}
56
57impl From<String> for Token {
58    fn from(arg: String) -> Self {
59        Symbol(arg.into_boxed_str())
60    }
61}
62
63impl From<Box<str>> for Token {
64    fn from(arg: Box<str>) -> Self {
65        Symbol(arg)
66    }
67}
68
69impl From<&str> for Token {
70    fn from(arg: &str) -> Self {
71        Symbol(arg.into())
72    }
73}
74
75impl<T: Copy + Into<Self>> From<&T> for Token {
76    fn from(arg: &T) -> Self {
77        (*arg).into()
78    }
79}
80
81impl<T: Into<Self>> From<Vec<T>> for Token {
82    fn from(list: Vec<T>) -> Self {
83        List(list.into_iter().map(T::into).collect())
84    }
85}
86
87mod implement_display {
88    use std::fmt::{Display, Formatter, Result};
89
90    use crate::Token;
91
92    impl Display for Token {
93        fn fmt(&self, f: &mut Formatter) -> Result {
94            match self {
95                Self::Symbol(string) => write!(f, "{string:?}"),
96                Self::List(vec) => {
97                    let mut first = true;
98                    write!(f, "(")?;
99                    for tok in vec {
100                        if first {
101                            first = false;
102                        } else {
103                            write!(f, " ")?;
104                        }
105                        write!(f, "{tok}")?;
106                    }
107                    write!(f, ")")
108                }
109            }
110        }
111    }
112}
113
114#[cfg(feature = "parser")]
115mod parser;