sise/
util.rs

1/// Returns whether `chr` is a valid atom character outside a
2/// string (i.e. one of `:atomchar:` documented at `TreeNode::Atom`).
3#[inline]
4pub const fn is_atom_chr(chr: char) -> bool {
5    matches!(
6        chr,
7        '!' | '#'
8            | '$'
9            | '%'
10            | '&'
11            | '*'
12            | '+'
13            | '-'
14            | '.'
15            | '/'
16            | '0'..='9'
17            | ':'
18            | '<'
19            | '='
20            | '>'
21            | '?'
22            | '@'
23            | 'A'..='Z'
24            | '_'
25            | 'a'..='z'
26            | '~'
27    )
28}
29
30/// Returns whether `chr` is a valid atom character inside a
31/// string, excluding `"` and `\` (i.e. one of `:stringchar:`
32/// documented at `TreeNode::Atom`).
33#[inline]
34pub const fn is_atom_string_chr(chr: char) -> bool {
35    matches!(chr, ' '..='~' if chr != '"' && chr != '\\')
36}
37
38/// Checks whether `atom` is a valid atom (i.e. matches the regular
39/// expression documented at `TreeNode::Atom`).
40pub fn check_atom(atom: &str) -> bool {
41    if atom.is_empty() {
42        // Empty atom
43        return false;
44    }
45
46    let mut iter = atom.chars();
47    let mut in_string = false;
48    loop {
49        if !in_string {
50            match iter.next() {
51                None => return true,
52                Some('"') => in_string = true,
53                Some(chr) if is_atom_chr(chr) => {}
54                // Invalid character
55                Some(_) => return false,
56            }
57        } else {
58            match iter.next() {
59                // Unfinished string
60                None => return false,
61                Some('"') => in_string = false,
62                Some('\\') => match iter.next() {
63                    Some('"' | '\\') => {}
64                    Some(chr) if is_atom_string_chr(chr) => {}
65                    // Invalid character or unfinished string
66                    Some(_) | None => return false,
67                },
68                Some(chr) if is_atom_string_chr(chr) => {}
69                // Invalid character
70                Some(_) => return false,
71            }
72        }
73    }
74}