1fad3a1d3Sopenharmony_cipub(crate) fn skip(mut s: &str) -> &str { 2fad3a1d3Sopenharmony_ci 'skip: while !s.is_empty() { 3fad3a1d3Sopenharmony_ci let byte = s.as_bytes()[0]; 4fad3a1d3Sopenharmony_ci if byte == b'/' { 5fad3a1d3Sopenharmony_ci if s.starts_with("//") 6fad3a1d3Sopenharmony_ci && (!s.starts_with("///") || s.starts_with("////")) 7fad3a1d3Sopenharmony_ci && !s.starts_with("//!") 8fad3a1d3Sopenharmony_ci { 9fad3a1d3Sopenharmony_ci if let Some(i) = s.find('\n') { 10fad3a1d3Sopenharmony_ci s = &s[i + 1..]; 11fad3a1d3Sopenharmony_ci continue; 12fad3a1d3Sopenharmony_ci } else { 13fad3a1d3Sopenharmony_ci return ""; 14fad3a1d3Sopenharmony_ci } 15fad3a1d3Sopenharmony_ci } else if s.starts_with("/**/") { 16fad3a1d3Sopenharmony_ci s = &s[4..]; 17fad3a1d3Sopenharmony_ci continue; 18fad3a1d3Sopenharmony_ci } else if s.starts_with("/*") 19fad3a1d3Sopenharmony_ci && (!s.starts_with("/**") || s.starts_with("/***")) 20fad3a1d3Sopenharmony_ci && !s.starts_with("/*!") 21fad3a1d3Sopenharmony_ci { 22fad3a1d3Sopenharmony_ci let mut depth = 0; 23fad3a1d3Sopenharmony_ci let bytes = s.as_bytes(); 24fad3a1d3Sopenharmony_ci let mut i = 0; 25fad3a1d3Sopenharmony_ci let upper = bytes.len() - 1; 26fad3a1d3Sopenharmony_ci while i < upper { 27fad3a1d3Sopenharmony_ci if bytes[i] == b'/' && bytes[i + 1] == b'*' { 28fad3a1d3Sopenharmony_ci depth += 1; 29fad3a1d3Sopenharmony_ci i += 1; // eat '*' 30fad3a1d3Sopenharmony_ci } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { 31fad3a1d3Sopenharmony_ci depth -= 1; 32fad3a1d3Sopenharmony_ci if depth == 0 { 33fad3a1d3Sopenharmony_ci s = &s[i + 2..]; 34fad3a1d3Sopenharmony_ci continue 'skip; 35fad3a1d3Sopenharmony_ci } 36fad3a1d3Sopenharmony_ci i += 1; // eat '/' 37fad3a1d3Sopenharmony_ci } 38fad3a1d3Sopenharmony_ci i += 1; 39fad3a1d3Sopenharmony_ci } 40fad3a1d3Sopenharmony_ci return s; 41fad3a1d3Sopenharmony_ci } 42fad3a1d3Sopenharmony_ci } 43fad3a1d3Sopenharmony_ci match byte { 44fad3a1d3Sopenharmony_ci b' ' | 0x09..=0x0d => { 45fad3a1d3Sopenharmony_ci s = &s[1..]; 46fad3a1d3Sopenharmony_ci continue; 47fad3a1d3Sopenharmony_ci } 48fad3a1d3Sopenharmony_ci b if b <= 0x7f => {} 49fad3a1d3Sopenharmony_ci _ => { 50fad3a1d3Sopenharmony_ci let ch = s.chars().next().unwrap(); 51fad3a1d3Sopenharmony_ci if is_whitespace(ch) { 52fad3a1d3Sopenharmony_ci s = &s[ch.len_utf8()..]; 53fad3a1d3Sopenharmony_ci continue; 54fad3a1d3Sopenharmony_ci } 55fad3a1d3Sopenharmony_ci } 56fad3a1d3Sopenharmony_ci } 57fad3a1d3Sopenharmony_ci return s; 58fad3a1d3Sopenharmony_ci } 59fad3a1d3Sopenharmony_ci s 60fad3a1d3Sopenharmony_ci} 61fad3a1d3Sopenharmony_ci 62fad3a1d3Sopenharmony_cifn is_whitespace(ch: char) -> bool { 63fad3a1d3Sopenharmony_ci // Rust treats left-to-right mark and right-to-left mark as whitespace 64fad3a1d3Sopenharmony_ci ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' 65fad3a1d3Sopenharmony_ci} 66