string_sections/
line_span.rs1use std::{
2 fmt,
3 ops::{Deref, Range},
4};
5
6use crate::str_to_range_unchecked;
7
8#[derive(PartialEq, Eq, Clone, Copy)]
9pub struct LineSpan<'a> {
10 pub(crate) text: &'a str,
11 pub start: usize,
12 pub end: usize,
13}
14
15impl<'a> LineSpan<'a> {
16 pub fn new(text: &'a str, substring: &str) -> Self {
17 let Range { start, end } = str_to_range_unchecked(text, substring);
18 LineSpan { text, start, end }
19 }
20
21 pub fn range(&self) -> Range<usize> {
25 self.start..self.end
26 }
27
28 pub fn as_str(&self) -> &'a str {
30 &self.text[self.range()]
31 }
32}
33
34impl<'a> Deref for LineSpan<'a> {
35 type Target = str;
36
37 fn deref(&self) -> &Self::Target {
38 self.as_str()
39 }
40}
41
42impl<'a> From<LineSpan<'a>> for &'a str {
43 fn from(span: LineSpan<'a>) -> &'a str {
44 span.as_str()
45 }
46}
47
48impl<'a> From<LineSpan<'a>> for Range<usize> {
49 fn from(span: LineSpan<'a>) -> Range<usize> {
50 span.range()
51 }
52}
53
54impl<'a> fmt::Debug for LineSpan<'a> {
55 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56 fmt.debug_struct("LineSpan")
57 .field("start", &self.start)
58 .field("end", &self.end)
59 .field("line", &self.as_str())
60 .finish()
61 }
62}
63
64impl<'a> fmt::Display for LineSpan<'a> {
65 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
66 self.as_str().fmt(fmt)
67 }
68}