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}