lib_ruby_parser/
maybe_byte.rs1#[derive(Debug, Clone, Copy)]
2pub(crate) enum MaybeByte {
3 Some(u8),
4 EndOfInput,
5}
6
7const PUNCT: [u8; 21] = [
8 b'!', b'"', b'$', b'&', b'\'', b'*', b'+', b',', b'.', b'/', b'0', b':', b';', b'<', b'=',
9 b'>', b'?', b'@', b'\\', b'`', b'~',
10];
11
12impl MaybeByte {
13 pub(crate) fn is_eof(&self) -> bool {
14 self == &MaybeByte::EndOfInput
15 }
16
17 pub(crate) fn is_some(&self) -> bool {
18 self != &MaybeByte::EndOfInput
19 }
20
21 pub(crate) fn expect(&self, msg: &str) -> u8 {
22 self.as_option().expect(msg)
23 }
24
25 pub(crate) fn as_option(&self) -> Option<u8> {
26 match self {
27 MaybeByte::Some(c) => Some(*c),
28 _ => None,
29 }
30 }
31
32 pub(crate) fn is_ascii(&self) -> bool {
33 if let Some(c) = self.as_option() {
34 c.is_ascii()
35 } else {
36 false
37 }
38 }
39
40 pub(crate) fn is_alpha(&self) -> bool {
41 if let Some(c) = self.as_option() {
42 c.is_ascii_alphabetic()
43 } else {
44 false
45 }
46 }
47
48 pub(crate) fn is_digit(&self) -> bool {
49 if let Some(c) = self.as_option() {
50 c.is_ascii_digit()
51 } else {
52 false
53 }
54 }
55
56 pub(crate) fn is_alnum(&self) -> bool {
57 if let Some(c) = self.as_option() {
58 c.is_ascii_alphanumeric()
59 } else {
60 false
61 }
62 }
63
64 pub(crate) fn is_hexdigit(&self) -> bool {
65 if let Some(c) = self.as_option() {
66 c.is_ascii_hexdigit()
67 } else {
68 false
69 }
70 }
71
72 pub(crate) fn is_space(&self) -> bool {
73 if let Some(c) = self.as_option() {
74 c == b' ' || (b'\t'..=b'\r').contains(&c)
75 } else {
76 false
77 }
78 }
79
80 pub(crate) fn is_global_name_punct(&self) -> bool {
81 if let Some(c) = self.as_option() {
82 PUNCT.contains(&c)
83 } else {
84 false
85 }
86 }
87
88 pub(crate) fn is_control(&self) -> bool {
89 if let Some(c) = self.as_option() {
90 (c as char).is_control()
91 } else {
92 false
93 }
94 }
95
96 pub(crate) fn map<F: FnOnce(u8) -> MaybeByte>(&self, f: F) -> MaybeByte {
97 match self.as_option() {
98 Some(c) => f(c),
99 _ => MaybeByte::EndOfInput,
100 }
101 }
102
103 pub(crate) fn escaped_control_code(&self) -> Option<u8> {
104 if *self == b' ' {
105 return Some(b's');
106 }
107 if *self == b'\n' {
108 return Some(b'n');
109 }
110 if *self == b'\t' {
111 return Some(b't');
112 }
113 if *self == 0x0b {
114 return Some(b'v');
115 }
116 if *self == b'\r' {
117 return Some(b'r');
118 }
119 if *self == 0x0c {
120 return Some(b'f');
121 }
122 None
123 }
124}
125
126pub(crate) trait MaybeByteNew<T> {
127 fn new(c: T) -> Self;
128}
129
130impl MaybeByteNew<u8> for MaybeByte {
131 fn new(byte: u8) -> Self {
132 MaybeByte::Some(byte)
133 }
134}
135
136impl PartialEq<u8> for MaybeByte {
137 fn eq(&self, other: &u8) -> bool {
138 match self {
139 MaybeByte::Some(c) => c == other,
140 MaybeByte::EndOfInput => false,
141 }
142 }
143}
144
145impl PartialEq<Option<u8>> for MaybeByte {
146 fn eq(&self, other: &Option<u8>) -> bool {
147 &self.as_option() == other
148 }
149}
150
151impl PartialEq for MaybeByte {
152 fn eq(&self, other: &MaybeByte) -> bool {
153 self.as_option() == other.as_option()
154 }
155}
156
157impl PartialOrd<u8> for MaybeByte {
158 fn partial_cmp(&self, other: &u8) -> Option<std::cmp::Ordering> {
159 match self.as_option() {
160 Some(c) => Some(c.cmp(other)),
161 _ => Some(std::cmp::Ordering::Less),
162 }
163 }
164}