summaryrefslogtreecommitdiffstats
path: root/vendor/pest/src/position.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/pest/src/position.rs')
-rw-r--r--vendor/pest/src/position.rs103
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::*;