1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
pub mod display; mod list; pub use self::list::get_error_desc; pub use self::list::ErrorInfo; pub use self::list::ErrorKind; pub use self::list::ParserError; macro_rules! error { ($kind:expr) => {{ Err(ParserError { info: None, kind: $kind, }) }}; } fn get_line_num(source: &str, pos: usize) -> usize { let mut ptr = 0; let mut i = 0; let lines = source.lines(); for line in lines { let lnlen = line.chars().count(); ptr += lnlen + 1; if ptr > pos { break; } i += 1; } i } pub fn get_error_lines(source: &str, start: usize, end: usize) -> String { let l = if start < end { end - start } else { 1 }; let lines = source.lines().skip(start).take(l); let mut s = String::new(); for line in lines { s.push_str(line); s.push('\n'); } String::from(s.trim_right()) } pub fn get_error_slice(source: &str, start: usize, end: usize) -> &str { let len = source.chars().count(); let start_pos; let mut slice_len = end - start; if len <= slice_len { start_pos = 0; slice_len = len; } else if start + slice_len >= len { start_pos = len - slice_len - 1; } else { start_pos = start; } let mut iter = source.chars(); if start_pos > 0 { iter.by_ref().nth(start_pos - 1); } let slice = iter.as_str(); let endp = slice .char_indices() .nth(slice_len) .map(|(n, _)| n) .unwrap_or(len); &slice[..endp] } pub fn get_error_info( source: &str, pos: usize, entry_start: usize, next_entry_start: usize, ) -> Option<ErrorInfo> { let first_line_num = get_line_num(source, entry_start); let next_entry_line = get_line_num(source, next_entry_start); let slice = get_error_lines(source, first_line_num, next_entry_line); Some(ErrorInfo { slice, line: first_line_num, pos: pos - entry_start, }) }