From 0ff08f3a9f8e1a9ddaacca917300dd62b82852ff Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Fri, 16 Feb 2018 16:56:25 -0800 Subject: [PATCH] Add Row::overall_indices --- src/utils/lines/spans/row.rs | 15 ++++++++++++++- src/utils/lines/spans/segment.rs | 22 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/utils/lines/spans/row.rs b/src/utils/lines/spans/row.rs index 33d202e..c75c205 100644 --- a/src/utils/lines/spans/row.rs +++ b/src/utils/lines/spans/row.rs @@ -1,5 +1,5 @@ use super::Segment; -use utils::span::{Span, AsSpannedStr}; +use utils::span::{AsSpannedStr, IndexedCow, Span}; /// A list of segments representing a row of text #[derive(Debug, Clone, PartialEq, Eq)] @@ -23,4 +23,17 @@ impl Row { .map(|seg| seg.resolve(source.clone())) .collect() } + + /// Returns indices in the source string, if possible. + /// + /// Returns overall `(start, end)`, or `None` if the segments are owned. + pub fn overall_indices(&self, spans: &[S]) -> Option<(usize, usize)> + where + S: AsRef, + { + let (start, _) = self.segments.get(0)?.source_indices(spans)?; + let (_, end) = self.segments.last()?.source_indices(spans)?; + + Some((start, end)) + } } diff --git a/src/utils/lines/spans/segment.rs b/src/utils/lines/spans/segment.rs index 104cbe4..0a9d9cf 100644 --- a/src/utils/lines/spans/segment.rs +++ b/src/utils/lines/spans/segment.rs @@ -1,4 +1,4 @@ -use utils::span::{SpannedStr, Span, SpannedText}; +use utils::span::{Span, SpannedStr, SpannedText, IndexedCow}; /// Refers to a part of a span #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -17,9 +17,7 @@ pub struct Segment { impl Segment { /// Resolve this segment to a string slice and an attribute. - pub fn resolve<'a, T>( - &self, source: SpannedStr<'a, T> - ) -> Span<'a, T> { + pub fn resolve<'a, T>(&self, source: SpannedStr<'a, T>) -> Span<'a, T> { let span = &source.spans_raw()[self.span_id]; let content = span.content.resolve(source.source()); @@ -43,4 +41,20 @@ impl Segment { content } + + /// Returns indices in the source string, if possible. + /// + /// Returns `(start, end)`, or `None` if the target span is an owned string. + pub fn source_indices(&self, spans: &[S]) -> Option<(usize, usize)> + where + S: AsRef, + { + let span = spans[self.span_id].as_ref(); + + if let &IndexedCow::Borrowed { start, .. } = span { + Some((self.start + start, self.end + start)) + } else { + None + } + } }