oom/source/
span.rs

1use std::fmt::Display;
2
3use crate::Position;
4
5#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct Span {
7    pub input: String,
8    pub start: Position,
9    pub end: Position,
10}
11impl Span {
12    pub fn new<T: Display>(input: T, start: (usize, usize), end: (usize, usize)) -> Span {
13        Span {
14            input: input.to_string(),
15            start: Position::from_tuple(start),
16            end: Position::from_tuple(end),
17        }
18    }
19
20    pub fn input(&self) -> &str {
21        self.input.as_str()
22    }
23
24    pub fn with_input(&self, input: &str) -> Span {
25        let mut info = self.clone();
26        info.input = input.to_string();
27        info
28    }
29
30    pub fn info(&self) -> Span {
31        self.clone()
32    }
33
34    pub fn start(&self) -> (usize, usize) {
35        self.start.to_tuple()
36    }
37
38    pub fn end(&self) -> (usize, usize) {
39        self.end.to_tuple()
40    }
41
42    pub fn highlight_input(&self, indent: usize) -> String {
43        crate::color::fore(self.highlight_input_chars(indent), 32)
44    }
45
46    fn highlight_input_chars(&self, indent: usize) -> String {
47        let start = self.start.clone();
48        let end = self.end.clone();
49        self.input
50            .lines()
51            .enumerate()
52            .map(|(no, line)| {
53                (
54                    no + 1,
55                    line.chars()
56                        .enumerate()
57                        .map(|(no, column)| (no + 1, column.to_string()))
58                        .collect::<Vec<(usize, String)>>(),
59                )
60            })
61            .map(|(line, columns)| {
62                crate::color::bg(
63                    format!(
64                        "{}{}",
65                        " ".repeat(indent),
66                        columns
67                            .iter()
68                            .map(|(column, text)| {
69                                let column = column.clone();
70                                if line == start.line && column == start.column {
71                                    crate::color::bgfg(text, 235, 198)
72                                } else if line == end.line && column == end.column {
73                                    [crate::color::reset(""), crate::color::bg(text, 235)].join("")
74                                } else {
75                                    crate::color::bg(text, 235)
76                                }
77                            })
78                            .collect::<String>()
79                    ),
80                    235,
81                )
82            })
83            .collect::<Vec<String>>()
84            .join("\n")
85    }
86}
87
88impl std::fmt::Display for Span {
89    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90        write!(f, "{}", &self.input)
91    }
92}
93
94impl Into<String> for Span {
95    fn into(self) -> String {
96        self.to_string()
97    }
98}
99
100impl Into<((usize, usize), (usize, usize))> for Span {
101    fn into(self) -> ((usize, usize), (usize, usize)) {
102        (self.start.to_tuple(), self.end.to_tuple())
103    }
104}