/rust/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.5.6/src/input.rs
Line | Count | Source |
1 | | use std::char; |
2 | | use std::cmp::Ordering; |
3 | | use std::fmt; |
4 | | use std::ops; |
5 | | use std::u32; |
6 | | |
7 | | use crate::literal::LiteralSearcher; |
8 | | use crate::prog::InstEmptyLook; |
9 | | use crate::utf8::{decode_last_utf8, decode_utf8}; |
10 | | |
11 | | /// Represents a location in the input. |
12 | | #[derive(Clone, Copy, Debug)] |
13 | | pub struct InputAt { |
14 | | pos: usize, |
15 | | c: Char, |
16 | | byte: Option<u8>, |
17 | | len: usize, |
18 | | } |
19 | | |
20 | | impl InputAt { |
21 | | /// Returns true iff this position is at the beginning of the input. |
22 | 90.1k | pub fn is_start(&self) -> bool { |
23 | 90.1k | self.pos == 0 |
24 | 90.1k | } <regex::input::InputAt>::is_start Line | Count | Source | 22 | 80.7k | pub fn is_start(&self) -> bool { | 23 | 80.7k | self.pos == 0 | 24 | 80.7k | } |
<regex::input::InputAt>::is_start Line | Count | Source | 22 | 9.42k | pub fn is_start(&self) -> bool { | 23 | 9.42k | self.pos == 0 | 24 | 9.42k | } |
|
25 | | |
26 | | /// Returns true iff this position is past the end of the input. |
27 | 0 | pub fn is_end(&self) -> bool { |
28 | 0 | self.c.is_none() && self.byte.is_none() |
29 | 0 | } Unexecuted instantiation: <regex::input::InputAt>::is_end Unexecuted instantiation: <regex::input::InputAt>::is_end |
30 | | |
31 | | /// Returns the character at this position. |
32 | | /// |
33 | | /// If this position is just before or after the input, then an absent |
34 | | /// character is returned. |
35 | 1.61M | pub fn char(&self) -> Char { |
36 | 1.61M | self.c |
37 | 1.61M | } <regex::input::InputAt>::char Line | Count | Source | 35 | 1.45M | pub fn char(&self) -> Char { | 36 | 1.45M | self.c | 37 | 1.45M | } |
<regex::input::InputAt>::char Line | Count | Source | 35 | 160k | pub fn char(&self) -> Char { | 36 | 160k | self.c | 37 | 160k | } |
|
38 | | |
39 | | /// Returns the byte at this position. |
40 | 0 | pub fn byte(&self) -> Option<u8> { |
41 | 0 | self.byte |
42 | 0 | } Unexecuted instantiation: <regex::input::InputAt>::byte Unexecuted instantiation: <regex::input::InputAt>::byte |
43 | | |
44 | | /// Returns the UTF-8 width of the character at this position. |
45 | 0 | pub fn len(&self) -> usize { |
46 | 0 | self.len |
47 | 0 | } Unexecuted instantiation: <regex::input::InputAt>::len Unexecuted instantiation: <regex::input::InputAt>::len |
48 | | |
49 | | /// Returns whether the UTF-8 width of the character at this position |
50 | | /// is zero. |
51 | 0 | pub fn is_empty(&self) -> bool { |
52 | 0 | self.len == 0 |
53 | 0 | } Unexecuted instantiation: <regex::input::InputAt>::is_empty Unexecuted instantiation: <regex::input::InputAt>::is_empty |
54 | | |
55 | | /// Returns the byte offset of this position. |
56 | 3.62M | pub fn pos(&self) -> usize { |
57 | 3.62M | self.pos |
58 | 3.62M | } <regex::input::InputAt>::pos Line | Count | Source | 56 | 3.26M | pub fn pos(&self) -> usize { | 57 | 3.26M | self.pos | 58 | 3.26M | } |
<regex::input::InputAt>::pos Line | Count | Source | 56 | 363k | pub fn pos(&self) -> usize { | 57 | 363k | self.pos | 58 | 363k | } |
|
59 | | |
60 | | /// Returns the byte offset of the next position in the input. |
61 | 882k | pub fn next_pos(&self) -> usize { |
62 | 882k | self.pos + self.len |
63 | 882k | } <regex::input::InputAt>::next_pos Line | Count | Source | 61 | 794k | pub fn next_pos(&self) -> usize { | 62 | 794k | self.pos + self.len | 63 | 794k | } |
<regex::input::InputAt>::next_pos Line | Count | Source | 61 | 87.5k | pub fn next_pos(&self) -> usize { | 62 | 87.5k | self.pos + self.len | 63 | 87.5k | } |
|
64 | | } |
65 | | |
66 | | /// An abstraction over input used in the matching engines. |
67 | | pub trait Input: fmt::Debug { |
68 | | /// Return an encoding of the position at byte offset `i`. |
69 | | fn at(&self, i: usize) -> InputAt; |
70 | | |
71 | | /// Return the Unicode character occurring next to `at`. |
72 | | /// |
73 | | /// If no such character could be decoded, then `Char` is absent. |
74 | | fn next_char(&self, at: InputAt) -> Char; |
75 | | |
76 | | /// Return the Unicode character occurring previous to `at`. |
77 | | /// |
78 | | /// If no such character could be decoded, then `Char` is absent. |
79 | | fn previous_char(&self, at: InputAt) -> Char; |
80 | | |
81 | | /// Return true if the given empty width instruction matches at the |
82 | | /// input position given. |
83 | | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool; |
84 | | |
85 | | /// Scan the input for a matching prefix. |
86 | | fn prefix_at( |
87 | | &self, |
88 | | prefixes: &LiteralSearcher, |
89 | | at: InputAt, |
90 | | ) -> Option<InputAt>; |
91 | | |
92 | | /// The number of bytes in the input. |
93 | | fn len(&self) -> usize; |
94 | | |
95 | | /// Whether the input is empty. |
96 | 0 | fn is_empty(&self) -> bool { |
97 | 0 | self.len() == 0 |
98 | 0 | } Unexecuted instantiation: <_ as regex::input::Input>::is_empty Unexecuted instantiation: <_ as regex::input::Input>::is_empty |
99 | | |
100 | | /// Return the given input as a sequence of bytes. |
101 | | fn as_bytes(&self) -> &[u8]; |
102 | | } |
103 | | |
104 | | impl<'a, T: Input> Input for &'a T { |
105 | 0 | fn at(&self, i: usize) -> InputAt { |
106 | 0 | (**self).at(i) |
107 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::at Unexecuted instantiation: <&_ as regex::input::Input>::at |
108 | | |
109 | 0 | fn next_char(&self, at: InputAt) -> Char { |
110 | 0 | (**self).next_char(at) |
111 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::next_char Unexecuted instantiation: <&_ as regex::input::Input>::next_char |
112 | | |
113 | 0 | fn previous_char(&self, at: InputAt) -> Char { |
114 | 0 | (**self).previous_char(at) |
115 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::previous_char Unexecuted instantiation: <&_ as regex::input::Input>::previous_char |
116 | | |
117 | 0 | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool { |
118 | 0 | (**self).is_empty_match(at, empty) |
119 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::is_empty_match Unexecuted instantiation: <&_ as regex::input::Input>::is_empty_match |
120 | | |
121 | 0 | fn prefix_at( |
122 | 0 | &self, |
123 | 0 | prefixes: &LiteralSearcher, |
124 | 0 | at: InputAt, |
125 | 0 | ) -> Option<InputAt> { |
126 | 0 | (**self).prefix_at(prefixes, at) |
127 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::prefix_at Unexecuted instantiation: <&_ as regex::input::Input>::prefix_at |
128 | | |
129 | 0 | fn len(&self) -> usize { |
130 | 0 | (**self).len() |
131 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::len Unexecuted instantiation: <&_ as regex::input::Input>::len |
132 | | |
133 | 0 | fn as_bytes(&self) -> &[u8] { |
134 | 0 | (**self).as_bytes() |
135 | 0 | } Unexecuted instantiation: <&_ as regex::input::Input>::as_bytes Unexecuted instantiation: <&_ as regex::input::Input>::as_bytes |
136 | | } |
137 | | |
138 | | /// An input reader over characters. |
139 | | #[derive(Clone, Copy, Debug)] |
140 | | pub struct CharInput<'t>(&'t [u8]); |
141 | | |
142 | | impl<'t> CharInput<'t> { |
143 | | /// Return a new character input reader for the given string. |
144 | 90.1k | pub fn new(s: &'t [u8]) -> CharInput<'t> { |
145 | 90.1k | CharInput(s) |
146 | 90.1k | } <regex::input::CharInput>::new Line | Count | Source | 144 | 80.7k | pub fn new(s: &'t [u8]) -> CharInput<'t> { | 145 | 80.7k | CharInput(s) | 146 | 80.7k | } |
<regex::input::CharInput>::new Line | Count | Source | 144 | 9.42k | pub fn new(s: &'t [u8]) -> CharInput<'t> { | 145 | 9.42k | CharInput(s) | 146 | 9.42k | } |
|
147 | | } |
148 | | |
149 | | impl<'t> ops::Deref for CharInput<'t> { |
150 | | type Target = [u8]; |
151 | | |
152 | 937k | fn deref(&self) -> &[u8] { |
153 | 937k | self.0 |
154 | 937k | } <regex::input::CharInput as core::ops::deref::Deref>::deref Line | Count | Source | 152 | 844k | fn deref(&self) -> &[u8] { | 153 | 844k | self.0 | 154 | 844k | } |
<regex::input::CharInput as core::ops::deref::Deref>::deref Line | Count | Source | 152 | 93.3k | fn deref(&self) -> &[u8] { | 153 | 93.3k | self.0 | 154 | 93.3k | } |
|
155 | | } |
156 | | |
157 | | impl<'t> Input for CharInput<'t> { |
158 | 972k | fn at(&self, i: usize) -> InputAt { |
159 | 972k | if i >= self.len() { |
160 | 34.4k | InputAt { pos: self.len(), c: None.into(), byte: None, len: 0 } |
161 | | } else { |
162 | 937k | let c = decode_utf8(&self[i..]).map(|(c, _)| c).into(); |
163 | 937k | InputAt { pos: i, c: c, byte: None, len: c.len_utf8() } |
164 | | } |
165 | 972k | } <regex::input::CharInput as regex::input::Input>::at Line | Count | Source | 158 | 875k | fn at(&self, i: usize) -> InputAt { | 159 | 875k | if i >= self.len() { | 160 | 30.8k | InputAt { pos: self.len(), c: None.into(), byte: None, len: 0 } | 161 | | } else { | 162 | 844k | let c = decode_utf8(&self[i..]).map(|(c, _)| c).into(); | 163 | 844k | InputAt { pos: i, c: c, byte: None, len: c.len_utf8() } | 164 | | } | 165 | 875k | } |
<regex::input::CharInput as regex::input::Input>::at Line | Count | Source | 158 | 96.9k | fn at(&self, i: usize) -> InputAt { | 159 | 96.9k | if i >= self.len() { | 160 | 3.61k | InputAt { pos: self.len(), c: None.into(), byte: None, len: 0 } | 161 | | } else { | 162 | 93.3k | let c = decode_utf8(&self[i..]).map(|(c, _)| c).into(); | 163 | 93.3k | InputAt { pos: i, c: c, byte: None, len: c.len_utf8() } | 164 | | } | 165 | 96.9k | } |
|
166 | | |
167 | 0 | fn next_char(&self, at: InputAt) -> Char { |
168 | 0 | at.char() |
169 | 0 | } Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::next_char Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::next_char |
170 | | |
171 | 0 | fn previous_char(&self, at: InputAt) -> Char { |
172 | 0 | decode_last_utf8(&self[..at.pos()]).map(|(c, _)| c).into() |
173 | 0 | } Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::previous_char Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::previous_char |
174 | | |
175 | 135k | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool { |
176 | | use crate::prog::EmptyLook::*; |
177 | 135k | match empty.look { |
178 | | StartLine => { |
179 | 0 | let c = self.previous_char(at); |
180 | 0 | at.pos() == 0 || c == '\n' |
181 | | } |
182 | | EndLine => { |
183 | 0 | let c = self.next_char(at); |
184 | 0 | at.pos() == self.len() || c == '\n' |
185 | | } |
186 | 90.1k | StartText => at.pos() == 0, |
187 | 45.4k | EndText => at.pos() == self.len(), |
188 | | WordBoundary => { |
189 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
190 | 0 | c1.is_word_char() != c2.is_word_char() |
191 | | } |
192 | | NotWordBoundary => { |
193 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
194 | 0 | c1.is_word_char() == c2.is_word_char() |
195 | | } |
196 | | WordBoundaryAscii => { |
197 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
198 | 0 | c1.is_word_byte() != c2.is_word_byte() |
199 | | } |
200 | | NotWordBoundaryAscii => { |
201 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
202 | 0 | c1.is_word_byte() == c2.is_word_byte() |
203 | | } |
204 | | } |
205 | 135k | } <regex::input::CharInput as regex::input::Input>::is_empty_match Line | Count | Source | 175 | 121k | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool { | 176 | | use crate::prog::EmptyLook::*; | 177 | 121k | match empty.look { | 178 | | StartLine => { | 179 | 0 | let c = self.previous_char(at); | 180 | 0 | at.pos() == 0 || c == '\n' | 181 | | } | 182 | | EndLine => { | 183 | 0 | let c = self.next_char(at); | 184 | 0 | at.pos() == self.len() || c == '\n' | 185 | | } | 186 | 80.7k | StartText => at.pos() == 0, | 187 | 40.6k | EndText => at.pos() == self.len(), | 188 | | WordBoundary => { | 189 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 190 | 0 | c1.is_word_char() != c2.is_word_char() | 191 | | } | 192 | | NotWordBoundary => { | 193 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 194 | 0 | c1.is_word_char() == c2.is_word_char() | 195 | | } | 196 | | WordBoundaryAscii => { | 197 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 198 | 0 | c1.is_word_byte() != c2.is_word_byte() | 199 | | } | 200 | | NotWordBoundaryAscii => { | 201 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 202 | 0 | c1.is_word_byte() == c2.is_word_byte() | 203 | | } | 204 | | } | 205 | 121k | } |
<regex::input::CharInput as regex::input::Input>::is_empty_match Line | Count | Source | 175 | 14.1k | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool { | 176 | | use crate::prog::EmptyLook::*; | 177 | 14.1k | match empty.look { | 178 | | StartLine => { | 179 | 0 | let c = self.previous_char(at); | 180 | 0 | at.pos() == 0 || c == '\n' | 181 | | } | 182 | | EndLine => { | 183 | 0 | let c = self.next_char(at); | 184 | 0 | at.pos() == self.len() || c == '\n' | 185 | | } | 186 | 9.42k | StartText => at.pos() == 0, | 187 | 4.73k | EndText => at.pos() == self.len(), | 188 | | WordBoundary => { | 189 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 190 | 0 | c1.is_word_char() != c2.is_word_char() | 191 | | } | 192 | | NotWordBoundary => { | 193 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 194 | 0 | c1.is_word_char() == c2.is_word_char() | 195 | | } | 196 | | WordBoundaryAscii => { | 197 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 198 | 0 | c1.is_word_byte() != c2.is_word_byte() | 199 | | } | 200 | | NotWordBoundaryAscii => { | 201 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); | 202 | 0 | c1.is_word_byte() == c2.is_word_byte() | 203 | | } | 204 | | } | 205 | 14.1k | } |
|
206 | | |
207 | 0 | fn prefix_at( |
208 | 0 | &self, |
209 | 0 | prefixes: &LiteralSearcher, |
210 | 0 | at: InputAt, |
211 | 0 | ) -> Option<InputAt> { |
212 | 0 | prefixes.find(&self[at.pos()..]).map(|(s, _)| self.at(at.pos() + s)) Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::prefix_at::{closure#0}Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::prefix_at::{closure#0} |
213 | 0 | } Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::prefix_at Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::prefix_at |
214 | | |
215 | 4.36M | fn len(&self) -> usize { |
216 | 4.36M | self.0.len() |
217 | 4.36M | } <regex::input::CharInput as regex::input::Input>::len Line | Count | Source | 215 | 3.92M | fn len(&self) -> usize { | 216 | 3.92M | self.0.len() | 217 | 3.92M | } |
<regex::input::CharInput as regex::input::Input>::len Line | Count | Source | 215 | 435k | fn len(&self) -> usize { | 216 | 435k | self.0.len() | 217 | 435k | } |
|
218 | | |
219 | 0 | fn as_bytes(&self) -> &[u8] { |
220 | 0 | self.0 |
221 | 0 | } Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::as_bytes Unexecuted instantiation: <regex::input::CharInput as regex::input::Input>::as_bytes |
222 | | } |
223 | | |
224 | | /// An input reader over bytes. |
225 | | #[derive(Clone, Copy, Debug)] |
226 | | pub struct ByteInput<'t> { |
227 | | text: &'t [u8], |
228 | | only_utf8: bool, |
229 | | } |
230 | | |
231 | | impl<'t> ByteInput<'t> { |
232 | | /// Return a new byte-based input reader for the given string. |
233 | 0 | pub fn new(text: &'t [u8], only_utf8: bool) -> ByteInput<'t> { |
234 | 0 | ByteInput { text: text, only_utf8: only_utf8 } |
235 | 0 | } Unexecuted instantiation: <regex::input::ByteInput>::new Unexecuted instantiation: <regex::input::ByteInput>::new |
236 | | } |
237 | | |
238 | | impl<'t> ops::Deref for ByteInput<'t> { |
239 | | type Target = [u8]; |
240 | | |
241 | 0 | fn deref(&self) -> &[u8] { |
242 | 0 | self.text |
243 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as core::ops::deref::Deref>::deref Unexecuted instantiation: <regex::input::ByteInput as core::ops::deref::Deref>::deref |
244 | | } |
245 | | |
246 | | impl<'t> Input for ByteInput<'t> { |
247 | 0 | fn at(&self, i: usize) -> InputAt { |
248 | 0 | if i >= self.len() { |
249 | 0 | InputAt { pos: self.len(), c: None.into(), byte: None, len: 0 } |
250 | | } else { |
251 | 0 | InputAt { |
252 | 0 | pos: i, |
253 | 0 | c: None.into(), |
254 | 0 | byte: self.get(i).cloned(), |
255 | 0 | len: 1, |
256 | 0 | } |
257 | | } |
258 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::at Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::at |
259 | | |
260 | 0 | fn next_char(&self, at: InputAt) -> Char { |
261 | 0 | decode_utf8(&self[at.pos()..]).map(|(c, _)| c).into() |
262 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::next_char Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::next_char |
263 | | |
264 | 0 | fn previous_char(&self, at: InputAt) -> Char { |
265 | 0 | decode_last_utf8(&self[..at.pos()]).map(|(c, _)| c).into() |
266 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::previous_char Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::previous_char |
267 | | |
268 | 0 | fn is_empty_match(&self, at: InputAt, empty: &InstEmptyLook) -> bool { |
269 | | use crate::prog::EmptyLook::*; |
270 | 0 | match empty.look { |
271 | | StartLine => { |
272 | 0 | let c = self.previous_char(at); |
273 | 0 | at.pos() == 0 || c == '\n' |
274 | | } |
275 | | EndLine => { |
276 | 0 | let c = self.next_char(at); |
277 | 0 | at.pos() == self.len() || c == '\n' |
278 | | } |
279 | 0 | StartText => at.pos() == 0, |
280 | 0 | EndText => at.pos() == self.len(), |
281 | | WordBoundary => { |
282 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
283 | 0 | c1.is_word_char() != c2.is_word_char() |
284 | | } |
285 | | NotWordBoundary => { |
286 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
287 | 0 | c1.is_word_char() == c2.is_word_char() |
288 | | } |
289 | | WordBoundaryAscii => { |
290 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
291 | 0 | if self.only_utf8 { |
292 | | // If we must match UTF-8, then we can't match word |
293 | | // boundaries at invalid UTF-8. |
294 | 0 | if c1.is_none() && !at.is_start() { |
295 | 0 | return false; |
296 | 0 | } |
297 | 0 | if c2.is_none() && !at.is_end() { |
298 | 0 | return false; |
299 | 0 | } |
300 | 0 | } |
301 | 0 | c1.is_word_byte() != c2.is_word_byte() |
302 | | } |
303 | | NotWordBoundaryAscii => { |
304 | 0 | let (c1, c2) = (self.previous_char(at), self.next_char(at)); |
305 | 0 | if self.only_utf8 { |
306 | | // If we must match UTF-8, then we can't match word |
307 | | // boundaries at invalid UTF-8. |
308 | 0 | if c1.is_none() && !at.is_start() { |
309 | 0 | return false; |
310 | 0 | } |
311 | 0 | if c2.is_none() && !at.is_end() { |
312 | 0 | return false; |
313 | 0 | } |
314 | 0 | } |
315 | 0 | c1.is_word_byte() == c2.is_word_byte() |
316 | | } |
317 | | } |
318 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::is_empty_match Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::is_empty_match |
319 | | |
320 | 0 | fn prefix_at( |
321 | 0 | &self, |
322 | 0 | prefixes: &LiteralSearcher, |
323 | 0 | at: InputAt, |
324 | 0 | ) -> Option<InputAt> { |
325 | 0 | prefixes.find(&self[at.pos()..]).map(|(s, _)| self.at(at.pos() + s)) Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::prefix_at::{closure#0}Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::prefix_at::{closure#0} |
326 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::prefix_at Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::prefix_at |
327 | | |
328 | 0 | fn len(&self) -> usize { |
329 | 0 | self.text.len() |
330 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::len Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::len |
331 | | |
332 | 0 | fn as_bytes(&self) -> &[u8] { |
333 | 0 | self.text |
334 | 0 | } Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::as_bytes Unexecuted instantiation: <regex::input::ByteInput as regex::input::Input>::as_bytes |
335 | | } |
336 | | |
337 | | /// An inline representation of `Option<char>`. |
338 | | /// |
339 | | /// This eliminates the need to do case analysis on `Option<char>` to determine |
340 | | /// ordinality with other characters. |
341 | | /// |
342 | | /// (The `Option<char>` is not related to encoding. Instead, it is used in the |
343 | | /// matching engines to represent the beginning and ending boundaries of the |
344 | | /// search text.) |
345 | | #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] |
346 | | pub struct Char(u32); |
347 | | |
348 | | impl fmt::Debug for Char { |
349 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
350 | 0 | match char::from_u32(self.0) { |
351 | 0 | None => write!(f, "Empty"), |
352 | 0 | Some(c) => write!(f, "{:?}", c), |
353 | | } |
354 | 0 | } Unexecuted instantiation: <regex::input::Char as core::fmt::Debug>::fmt Unexecuted instantiation: <regex::input::Char as core::fmt::Debug>::fmt |
355 | | } |
356 | | |
357 | | impl Char { |
358 | | /// Returns true iff the character is absent. |
359 | | #[inline] |
360 | 0 | pub fn is_none(self) -> bool { |
361 | 0 | self.0 == u32::MAX |
362 | 0 | } Unexecuted instantiation: <regex::input::Char>::is_none Unexecuted instantiation: <regex::input::Char>::is_none |
363 | | |
364 | | /// Returns the length of the character's UTF-8 encoding. |
365 | | /// |
366 | | /// If the character is absent, then `1` is returned. |
367 | | #[inline] |
368 | 937k | pub fn len_utf8(self) -> usize { |
369 | 937k | char::from_u32(self.0).map_or(1, |c| c.len_utf8()) <regex::input::Char>::len_utf8::{closure#0}Line | Count | Source | 369 | 844k | char::from_u32(self.0).map_or(1, |c| c.len_utf8()) |
<regex::input::Char>::len_utf8::{closure#0}Line | Count | Source | 369 | 93.3k | char::from_u32(self.0).map_or(1, |c| c.len_utf8()) |
|
370 | 937k | } <regex::input::Char>::len_utf8 Line | Count | Source | 368 | 844k | pub fn len_utf8(self) -> usize { | 369 | 844k | char::from_u32(self.0).map_or(1, |c| c.len_utf8()) | 370 | 844k | } |
<regex::input::Char>::len_utf8 Line | Count | Source | 368 | 93.3k | pub fn len_utf8(self) -> usize { | 369 | 93.3k | char::from_u32(self.0).map_or(1, |c| c.len_utf8()) | 370 | 93.3k | } |
|
371 | | |
372 | | /// Returns true iff the character is a word character. |
373 | | /// |
374 | | /// If the character is absent, then false is returned. |
375 | 0 | pub fn is_word_char(self) -> bool { |
376 | | // is_word_character can panic if the Unicode data for \w isn't |
377 | | // available. However, our compiler ensures that if a Unicode word |
378 | | // boundary is used, then the data must also be available. If it isn't, |
379 | | // then the compiler returns an error. |
380 | 0 | char::from_u32(self.0).map_or(false, regex_syntax::is_word_character) |
381 | 0 | } Unexecuted instantiation: <regex::input::Char>::is_word_char Unexecuted instantiation: <regex::input::Char>::is_word_char |
382 | | |
383 | | /// Returns true iff the byte is a word byte. |
384 | | /// |
385 | | /// If the byte is absent, then false is returned. |
386 | 0 | pub fn is_word_byte(self) -> bool { |
387 | 0 | match char::from_u32(self.0) { |
388 | 0 | Some(c) if c <= '\u{7F}' => regex_syntax::is_word_byte(c as u8), |
389 | 0 | None | Some(_) => false, |
390 | | } |
391 | 0 | } Unexecuted instantiation: <regex::input::Char>::is_word_byte Unexecuted instantiation: <regex::input::Char>::is_word_byte |
392 | | } |
393 | | |
394 | | impl From<char> for Char { |
395 | 937k | fn from(c: char) -> Char { |
396 | 937k | Char(c as u32) |
397 | 937k | } <regex::input::Char as core::convert::From<char>>::from Line | Count | Source | 395 | 844k | fn from(c: char) -> Char { | 396 | 844k | Char(c as u32) | 397 | 844k | } |
<regex::input::Char as core::convert::From<char>>::from Line | Count | Source | 395 | 93.3k | fn from(c: char) -> Char { | 396 | 93.3k | Char(c as u32) | 397 | 93.3k | } |
|
398 | | } |
399 | | |
400 | | impl From<Option<char>> for Char { |
401 | 972k | fn from(c: Option<char>) -> Char { |
402 | 972k | c.map_or(Char(u32::MAX), |c| c.into()) <regex::input::Char as core::convert::From<core::option::Option<char>>>::from::{closure#0}Line | Count | Source | 402 | 844k | c.map_or(Char(u32::MAX), |c| c.into()) |
<regex::input::Char as core::convert::From<core::option::Option<char>>>::from::{closure#0}Line | Count | Source | 402 | 93.3k | c.map_or(Char(u32::MAX), |c| c.into()) |
|
403 | 972k | } <regex::input::Char as core::convert::From<core::option::Option<char>>>::from Line | Count | Source | 401 | 875k | fn from(c: Option<char>) -> Char { | 402 | 875k | c.map_or(Char(u32::MAX), |c| c.into()) | 403 | 875k | } |
<regex::input::Char as core::convert::From<core::option::Option<char>>>::from Line | Count | Source | 401 | 96.9k | fn from(c: Option<char>) -> Char { | 402 | 96.9k | c.map_or(Char(u32::MAX), |c| c.into()) | 403 | 96.9k | } |
|
404 | | } |
405 | | |
406 | | impl PartialEq<char> for Char { |
407 | | #[inline] |
408 | 0 | fn eq(&self, other: &char) -> bool { |
409 | 0 | self.0 == *other as u32 |
410 | 0 | } Unexecuted instantiation: <regex::input::Char as core::cmp::PartialEq<char>>::eq Unexecuted instantiation: <regex::input::Char as core::cmp::PartialEq<char>>::eq |
411 | | } |
412 | | |
413 | | impl PartialEq<Char> for char { |
414 | | #[inline] |
415 | 738k | fn eq(&self, other: &Char) -> bool { |
416 | 738k | *self as u32 == other.0 |
417 | 738k | } <char as core::cmp::PartialEq<regex::input::Char>>::eq Line | Count | Source | 415 | 666k | fn eq(&self, other: &Char) -> bool { | 416 | 666k | *self as u32 == other.0 | 417 | 666k | } |
<char as core::cmp::PartialEq<regex::input::Char>>::eq Line | Count | Source | 415 | 72.4k | fn eq(&self, other: &Char) -> bool { | 416 | 72.4k | *self as u32 == other.0 | 417 | 72.4k | } |
|
418 | | } |
419 | | |
420 | | impl PartialOrd<char> for Char { |
421 | | #[inline] |
422 | 3.24M | fn partial_cmp(&self, other: &char) -> Option<Ordering> { |
423 | 3.24M | self.0.partial_cmp(&(*other as u32)) |
424 | 3.24M | } <regex::input::Char as core::cmp::PartialOrd<char>>::partial_cmp Line | Count | Source | 422 | 2.91M | fn partial_cmp(&self, other: &char) -> Option<Ordering> { | 423 | 2.91M | self.0.partial_cmp(&(*other as u32)) | 424 | 2.91M | } |
<regex::input::Char as core::cmp::PartialOrd<char>>::partial_cmp Line | Count | Source | 422 | 331k | fn partial_cmp(&self, other: &char) -> Option<Ordering> { | 423 | 331k | self.0.partial_cmp(&(*other as u32)) | 424 | 331k | } |
|
425 | | } |
426 | | |
427 | | impl PartialOrd<Char> for char { |
428 | | #[inline] |
429 | 729k | fn partial_cmp(&self, other: &Char) -> Option<Ordering> { |
430 | 729k | (*self as u32).partial_cmp(&other.0) |
431 | 729k | } <char as core::cmp::PartialOrd<regex::input::Char>>::partial_cmp Line | Count | Source | 429 | 652k | fn partial_cmp(&self, other: &Char) -> Option<Ordering> { | 430 | 652k | (*self as u32).partial_cmp(&other.0) | 431 | 652k | } |
<char as core::cmp::PartialOrd<regex::input::Char>>::partial_cmp Line | Count | Source | 429 | 76.2k | fn partial_cmp(&self, other: &Char) -> Option<Ordering> { | 430 | 76.2k | (*self as u32).partial_cmp(&other.0) | 431 | 76.2k | } |
|
432 | | } |