diff options
Diffstat (limited to 'vendor/pest/src/position.rs')
-rw-r--r-- | vendor/pest/src/position.rs | 103 |
1 files changed, 39 insertions, 64 deletions
diff --git a/vendor/pest/src/position.rs b/vendor/pest/src/position.rs index f91f8291e..465ff9766 100644 --- a/vendor/pest/src/position.rs +++ b/vendor/pest/src/position.rs @@ -116,6 +116,9 @@ impl<'i> Position<'i> { /// Returns the line and column number of this `Position`. /// + /// This is an O(n) operation, where n is the number of chars in the input. + /// You better use [`pair.line_col()`](struct.Pair.html#method.line_col) instead. + /// /// # Examples /// /// ``` @@ -135,14 +138,43 @@ impl<'i> Position<'i> { if self.pos > self.input.len() { panic!("position out of bounds"); } - #[cfg(feature = "fast-line-col")] - { - fast_line_col(self.input, self.pos) - } - #[cfg(not(feature = "fast-line-col"))] - { - original_line_col(self.input, self.pos) + let mut pos = self.pos; + let slice = &self.input[..pos]; + let mut chars = slice.chars().peekable(); + + let mut line_col = (1, 1); + + while pos != 0 { + match chars.next() { + Some('\r') => { + if let Some(&'\n') = chars.peek() { + chars.next(); + + if pos == 1 { + pos -= 1; + } else { + pos -= 2; + } + + line_col = (line_col.0 + 1, 1); + } else { + pos -= 1; + line_col = (line_col.0, line_col.1 + 1); + } + } + Some('\n') => { + pos -= 1; + line_col = (line_col.0 + 1, 1); + } + Some(c) => { + pos -= c.len_utf8(); + line_col = (line_col.0, line_col.1 + 1); + } + None => unreachable!(), + } } + + line_col } /// Returns the entire line of the input that contains this `Position`. @@ -455,63 +487,6 @@ impl<'i> Hash for Position<'i> { } } -#[inline] -#[cfg(not(feature = "fast-line-col"))] -fn original_line_col(input: &str, mut pos: usize) -> (usize, usize) { - // Position's pos is always a UTF-8 border. - let slice = &input[..pos]; - let mut chars = slice.chars().peekable(); - - let mut line_col = (1, 1); - - while pos != 0 { - match chars.next() { - Some('\r') => { - if let Some(&'\n') = chars.peek() { - chars.next(); - - if pos == 1 { - pos -= 1; - } else { - pos -= 2; - } - - line_col = (line_col.0 + 1, 1); - } else { - pos -= 1; - line_col = (line_col.0, line_col.1 + 1); - } - } - Some('\n') => { - pos -= 1; - line_col = (line_col.0 + 1, 1); - } - Some(c) => { - pos -= c.len_utf8(); - line_col = (line_col.0, line_col.1 + 1); - } - None => unreachable!(), - } - } - - line_col -} - -#[inline] -#[cfg(feature = "fast-line-col")] -fn fast_line_col(input: &str, pos: usize) -> (usize, usize) { - // Position's pos is always a UTF-8 border. - let slice = &input[..pos]; - - let prec_ln = memchr::memrchr(b'\n', slice.as_bytes()); - if let Some(prec_nl_pos) = prec_ln { - let lines = bytecount::count(slice[..=prec_nl_pos].as_bytes(), b'\n') + 1; - (lines, slice[prec_nl_pos..].chars().count()) - } else { - (1, slice.chars().count() + 1) - } -} - #[cfg(test)] mod tests { use super::*; |