| // SPDX-License-Identifier: Apache-2.0 OR MIT | |
| pub(crate) fn skip(mut s: &str) -> &str { | |
| 'skip: while !s.is_empty() { | |
| let byte = s.as_bytes()[0]; | |
| if byte == b'/' { | |
| if s.starts_with("//") | |
| && (!s.starts_with("///") || s.starts_with("////")) | |
| && !s.starts_with("//!") | |
| { | |
| if let Some(i) = s.find('\n') { | |
| s = &s[i + 1..]; | |
| continue; | |
| } else { | |
| return ""; | |
| } | |
| } else if s.starts_with("/**/") { | |
| s = &s[4..]; | |
| continue; | |
| } else if s.starts_with("/*") | |
| && (!s.starts_with("/**") || s.starts_with("/***")) | |
| && !s.starts_with("/*!") | |
| { | |
| let mut depth = 0; | |
| let bytes = s.as_bytes(); | |
| let mut i = 0; | |
| let upper = bytes.len() - 1; | |
| while i < upper { | |
| if bytes[i] == b'/' && bytes[i + 1] == b'*' { | |
| depth += 1; | |
| i += 1; // eat '*' | |
| } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { | |
| depth -= 1; | |
| if depth == 0 { | |
| s = &s[i + 2..]; | |
| continue 'skip; | |
| } | |
| i += 1; // eat '/' | |
| } | |
| i += 1; | |
| } | |
| return s; | |
| } | |
| } | |
| match byte { | |
| b' ' | 0x09..=0x0D => { | |
| s = &s[1..]; | |
| continue; | |
| } | |
| b if b <= 0x7F => {} | |
| _ => { | |
| let ch = s.chars().next().unwrap(); | |
| if is_whitespace(ch) { | |
| s = &s[ch.len_utf8()..]; | |
| continue; | |
| } | |
| } | |
| } | |
| return s; | |
| } | |
| s | |
| } | |
| fn is_whitespace(ch: char) -> bool { | |
| // Rust treats left-to-right mark and right-to-left mark as whitespace | |
| ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' | |
| } |