rustre_parser/
location.rs

1#[derive(Default, PartialEq, Clone, Debug)]
2pub struct Location {
3    pub line: u64,
4    pub col: u64,
5    pub pos: u64,
6}
7
8#[derive(Default, PartialEq, Clone)]
9pub struct Span<'f> {
10    pub file: &'f str,
11    pub start: Location,
12    pub end: Location,
13}
14
15impl<'f> std::fmt::Debug for Span<'f> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.write_fmt(format_args!(
18            "'{}' {}:{}..{}:{}",
19            self.file, self.start.line, self.start.col, self.end.line, self.end.col
20        ))
21    }
22}
23
24#[derive(PartialEq)]
25pub struct Spanned<'f, T> {
26    pub span: Span<'f>,
27    pub item: T,
28}
29
30impl<'f, T: std::fmt::Debug> std::fmt::Debug for Spanned<'f, T> {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        f.write_fmt(format_args!(
33            "{:#?} \x1b[38;5;240m@ {:?}\x1b[0m",
34            self.item, self.span
35        ))
36    }
37}
38
39impl<'f, T: Clone> Clone for Spanned<'f, T> {
40    fn clone(&self) -> Self {
41        Self {
42            span: self.span.clone(),
43            item: self.item.clone(),
44        }
45    }
46}
47
48impl<'f, T> From<Spanned<'f, T>> for Span<'f> {
49    fn from(spanned: Spanned<'f, T>) -> Span<'f> {
50        spanned.span
51    }
52}
53
54impl<'a, 'f, T: std::fmt::Debug> From<&'a Spanned<'f, T>> for Span<'f> {
55    fn from(spanned: &'a Spanned<'f, T>) -> Span<'f> {
56        spanned.span.clone()
57    }
58}
59
60impl<'f, T: std::fmt::Debug> Spanned<'f, T> {
61    pub fn fusion(start: impl Into<Span<'f>>, end: impl Into<Span<'f>>, item: T) -> Self {
62        let start = start.into();
63        let end = end.into();
64        let span = Span {
65            file: start.file, // TODO: panic if start.file != end.file ?
66            start: start.start,
67            end: end.end,
68        };
69        Self { span, item }
70    }
71}
72
73impl<'f, T> Spanned<'f, T> {
74    pub fn boxed(self) -> Spanned<'f, Box<T>> {
75        self.map(Box::new)
76    }
77
78    pub fn map_ref<F, U>(&self, f: F) -> Spanned<'f, U>
79    where
80        F: Fn(&T) -> U,
81    {
82        Spanned {
83            span: self.span.clone(),
84            item: f(&self.item),
85        }
86    }
87
88    pub fn map<F, U>(self, f: F) -> Spanned<'f, U>
89    where
90        F: FnOnce(T) -> U,
91    {
92        Spanned {
93            span: self.span,
94            item: f(self.item),
95        }
96    }
97}