blob: 3726faa5061daf4c636cf16ac652ba69694ec232 [file] [log] [blame]
David Tolnay14cbdeb2016-10-01 12:13:59 -07001use nom::IResult;
2use unicode_xid::UnicodeXID;
3
4pub fn whitespace(input: &str) -> IResult<&str, ()> {
5 if input.is_empty() {
6 return IResult::Error;
7 }
8
9 let mut start = 0;
10 let mut chars = input.char_indices();
11 while let Some((i, ch)) = chars.next() {
12 let s = &input[start + i..];
13 if ch == '/' {
David Tolnaydaaf7742016-10-03 11:11:43 -070014 if s.starts_with("//") && (!s.starts_with("///") || s.starts_with("////")) &&
15 !s.starts_with("//!") {
David Tolnay14cbdeb2016-10-01 12:13:59 -070016 if let Some(len) = s.find('\n') {
17 start += i + len + 1;
18 chars = input[start..].char_indices();
19 continue;
20 }
21 break;
David Tolnaydaaf7742016-10-03 11:11:43 -070022 } else if s.starts_with("/*") && !s.starts_with("/**") && !s.starts_with("/*!") {
David Tolnay14cbdeb2016-10-01 12:13:59 -070023 match block_comment(s) {
24 IResult::Done(_, com) => {
25 start += i + com.len();
26 chars = input[start..].char_indices();
27 continue;
28 }
29 IResult::Error => {
30 return IResult::Error;
31 }
32 }
33 }
34 }
35 if !ch.is_whitespace() {
36 return if start + i > 0 {
37 IResult::Done(s, ())
38 } else {
39 IResult::Error
40 };
41 }
42 }
43 IResult::Done("", ())
44}
45
46pub fn block_comment(input: &str) -> IResult<&str, &str> {
47 if !input.starts_with("/*") {
48 return IResult::Error;
49 }
50
51 let mut depth = 0;
David Tolnay079b5ad2016-10-08 09:39:29 -070052 let bytes = input.as_bytes();
53 let mut i = 0;
54 let upper = bytes.len() - 1;
55 while i < upper {
56 if bytes[i] == b'/' && bytes[i + 1] == b'*' {
David Tolnay14cbdeb2016-10-01 12:13:59 -070057 depth += 1;
David Tolnay079b5ad2016-10-08 09:39:29 -070058 i += 1; // eat '*'
59 } else if bytes[i] == b'*' && bytes[i + 1] == b'/' {
David Tolnay14cbdeb2016-10-01 12:13:59 -070060 depth -= 1;
61 if depth == 0 {
62 return IResult::Done(&input[i + 2..], &input[..i + 2]);
63 }
David Tolnay079b5ad2016-10-08 09:39:29 -070064 i += 1; // eat '/'
David Tolnay14cbdeb2016-10-01 12:13:59 -070065 }
David Tolnay079b5ad2016-10-08 09:39:29 -070066 i += 1;
David Tolnay14cbdeb2016-10-01 12:13:59 -070067 }
68 IResult::Error
69}
70
71pub fn word_break(input: &str) -> IResult<&str, ()> {
72 match input.chars().next() {
David Tolnaydaaf7742016-10-03 11:11:43 -070073 Some(ch) if UnicodeXID::is_xid_continue(ch) => IResult::Error,
74 Some(_) | None => IResult::Done(input, ()),
David Tolnay14cbdeb2016-10-01 12:13:59 -070075 }
76}