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
use super::Segment;
use crate::utils::span::{IndexedCow, Span, SpannedStr};

/// A list of segments representing a row of text
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Row {
    /// List of segments
    pub segments: Vec<Segment>,
    /// Total width for this row
    pub width: usize,
}

impl Row {
    /// Resolve the row indices into string slices and attributes.
    pub fn resolve<'a, T, S>(&self, source: S) -> Vec<Span<'a, T>>
    where
        S: Into<SpannedStr<'a, T>>,
    {
        let source = source.into();

        self.segments
            .iter()
            .map(|seg| seg.resolve(&source))
            .filter(|span| !span.content.is_empty())
            .collect()
    }

    /// Returns indices in the source string, if possible.
    ///
    /// Returns overall `(start, end)`, or `None` if the segments are owned.
    pub fn overall_indices<S>(&self, spans: &[S]) -> Option<(usize, usize)>
    where
        S: AsRef<IndexedCow>,
    {
        let (start, _) = self.segments.first()?.source_indices(spans)?;
        let (_, end) = self.segments.last()?.source_indices(spans)?;

        Some((start, end))
    }
}