diff options
Diffstat (limited to 'vendor/pest/src/span.rs')
-rw-r--r-- | vendor/pest/src/span.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/vendor/pest/src/span.rs b/vendor/pest/src/span.rs index 7603c43c5..bf7b12be8 100644 --- a/vendor/pest/src/span.rs +++ b/vendor/pest/src/span.rs @@ -212,6 +212,27 @@ impl<'i> Span<'i> { &self.input[self.start..self.end] } + /// Returns the input string of the `Span`. + /// + /// This function returns the input string of the `Span` as a `&str`. This is the source string + /// from which the `Span` was created. The returned `&str` can be used to examine the contents of + /// the `Span` or to perform further processing on the string. + /// + /// # Examples + /// + /// ``` + /// # use pest; + /// # use pest::Span; + /// + /// // Example: Get input string from a span + /// let input = "abc\ndef\nghi"; + /// let span = Span::new(input, 1, 7).unwrap(); + /// assert_eq!(span.get_input(), input); + /// ``` + pub fn get_input(&self) -> &'i str { + self.input + } + /// Iterates over all lines (partially) covered by this span. Yielding a `&str` for each line. /// /// # Examples @@ -288,6 +309,61 @@ impl<'i> Hash for Span<'i> { } } +/// Merges two spans into one. +/// +/// This function merges two spans that are contiguous or overlapping into a single span +/// that covers the entire range of the two input spans. This is useful when you want to +/// aggregate information from multiple spans into a single entity. +/// +/// The function checks if the input spans are overlapping or contiguous by comparing their +/// start and end positions. If they are, a new span is created with the minimum start position +/// and the maximum end position of the two input spans. +/// +/// If the input spans are neither overlapping nor contiguous, the function returns None, +/// indicating that a merge operation was not possible. +/// +/// # Examples +/// +/// ``` +/// # use pest; +/// # use pest::Span; +/// # use pest::merge_spans; +/// +/// // Example 1: Contiguous spans +/// let input = "abc\ndef\nghi"; +/// let span1 = Span::new(input, 1, 7).unwrap(); +/// let span2 = Span::new(input, 7, 11).unwrap(); +/// let merged = merge_spans(&span1, &span2).unwrap(); +/// assert_eq!(merged, Span::new(input, 1, 11).unwrap()); +/// +/// // Example 2: Overlapping spans +/// let input = "abc\ndef\nghi"; +/// let span1 = Span::new(input, 1, 7).unwrap(); +/// let span2 = Span::new(input, 5, 11).unwrap(); +/// let merged = merge_spans(&span1, &span2).unwrap(); +/// assert_eq!(merged, Span::new(input, 1, 11).unwrap()); +/// +/// // Example 3: Non-contiguous spans +/// let input = "abc\ndef\nghi"; +/// let span1 = Span::new(input, 1, 7).unwrap(); +/// let span2 = Span::new(input, 8, 11).unwrap(); +/// let merged = merge_spans(&span1, &span2); +/// assert!(merged.is_none()); +/// ``` +pub fn merge_spans<'i>(a: &Span<'i>, b: &Span<'i>) -> Option<Span<'i>> { + if a.end() >= b.start() && a.start() <= b.end() { + // The spans overlap or are contiguous, so they can be merged. + Span::new( + a.get_input(), + core::cmp::min(a.start(), b.start()), + core::cmp::max(a.end(), b.end()), + ) + } else { + // The spans don't overlap and aren't contiguous, so they can't be merged. + None + } +} + /// Line iterator for Spans, created by [`Span::lines_span()`]. /// /// Iterates all lines that are at least _partially_ covered by the span. Yielding a `Span` for each. @@ -447,4 +523,42 @@ mod tests { lines ); } + + #[test] + fn get_input_of_span() { + let input = "abc\ndef\nghi"; + let span = Span::new(input, 1, 7).unwrap(); + + assert_eq!(span.get_input(), input); + } + + #[test] + fn merge_contiguous() { + let input = "abc\ndef\nghi"; + let span1 = Span::new(input, 1, 7).unwrap(); + let span2 = Span::new(input, 7, 11).unwrap(); + let merged = merge_spans(&span1, &span2).unwrap(); + + assert_eq!(merged, Span::new(input, 1, 11).unwrap()); + } + + #[test] + fn merge_overlapping() { + let input = "abc\ndef\nghi"; + let span1 = Span::new(input, 1, 7).unwrap(); + let span2 = Span::new(input, 5, 11).unwrap(); + let merged = merge_spans(&span1, &span2).unwrap(); + + assert_eq!(merged, Span::new(input, 1, 11).unwrap()); + } + + #[test] + fn merge_non_contiguous() { + let input = "abc\ndef\nghi"; + let span1 = Span::new(input, 1, 7).unwrap(); + let span2 = Span::new(input, 8, 11).unwrap(); + let merged = merge_spans(&span1, &span2); + + assert!(merged.is_none()); + } } |