Skip to main content

globetrotter_model/
diagnostics.rs

1use codespan_reporting::diagnostic::{self, Diagnostic, Label, Severity};
2use indexmap::IndexMap;
3
4pub type FileId = usize;
5pub type Span = std::ops::Range<usize>;
6
7pub trait ToDiagnostics {
8    fn to_diagnostics<F: Copy + PartialEq>(&self, file_id: F) -> Vec<Diagnostic<F>>;
9}
10
11pub trait DiagnosticExt {
12    fn is_error(&self) -> bool;
13    fn is_warning(&self) -> bool;
14    fn warning_or_error(strict: bool) -> Self;
15}
16
17impl<F> DiagnosticExt for Diagnostic<F> {
18    fn is_error(&self) -> bool {
19        match self.severity {
20            Severity::Bug | Severity::Error => true,
21            Severity::Warning | Severity::Note | Severity::Help => false,
22        }
23    }
24
25    fn is_warning(&self) -> bool {
26        match self.severity {
27            Severity::Warning => true,
28            Severity::Bug | Severity::Error | Severity::Note | Severity::Help => false,
29        }
30    }
31
32    fn warning_or_error(strict: bool) -> Self {
33        if strict {
34            Self::error()
35        } else {
36            Self::warning()
37        }
38    }
39}
40
41pub struct DisplayRepr<'a, T>(pub &'a T);
42
43// impl<'a, T> tracing::Value for DisplayRepr<'a, T> {
44//     fn record(&self, key: &tracing::field::Field, visitor: &mut dyn tracing::field::Visit) {
45//
46//     }
47// }
48
49impl<T> std::fmt::Debug for DisplayRepr<'_, T>
50where
51    T: std::fmt::Display,
52{
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        std::fmt::Display::fmt(self.0, f)
55    }
56}
57
58impl<T> std::fmt::Display for DisplayRepr<'_, T>
59where
60    T: std::fmt::Display,
61{
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        std::fmt::Display::fmt(self.0, f)
64    }
65}
66
67#[derive(Debug, Clone)]
68pub struct Spanned<T> {
69    pub inner: T,
70    pub span: Span,
71}
72
73impl<T> serde::Serialize for Spanned<T>
74where
75    T: serde::Serialize,
76{
77    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78    where
79        S: serde::Serializer,
80    {
81        self.inner.serialize(serializer)
82    }
83}
84
85impl<T> std::ops::Deref for Spanned<T> {
86    type Target = T;
87    fn deref(&self) -> &Self::Target {
88        &self.inner
89    }
90}
91
92impl<T> AsRef<T> for Spanned<T> {
93    fn as_ref(&self) -> &T {
94        &self.inner
95    }
96}
97
98impl<T> Spanned<T> {
99    pub fn new(span: impl Into<Span>, value: T) -> Self {
100        Self {
101            span: span.into(),
102            inner: value,
103        }
104    }
105
106    pub fn dummy(value: T) -> Self {
107        Self {
108            span: Span::default(),
109            inner: value,
110        }
111    }
112
113    pub fn into_inner(self) -> T {
114        self.inner
115    }
116
117    pub fn display(&self) -> DisplayRepr<'_, Self> {
118        DisplayRepr(self)
119    }
120}
121
122impl<T> std::fmt::Display for Spanned<T>
123where
124    T: std::fmt::Display,
125{
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        std::fmt::Display::fmt(&self.inner, f)
128    }
129}
130
131impl<T> PartialEq for Spanned<T>
132where
133    T: PartialEq,
134{
135    fn eq(&self, other: &Self) -> bool {
136        self.inner == other.inner
137    }
138}
139
140impl<T> PartialEq<T> for Spanned<T>
141where
142    T: PartialEq,
143{
144    fn eq(&self, other: &T) -> bool {
145        (&self.inner as &dyn PartialEq<T>).eq(other)
146    }
147}
148
149impl<T> PartialEq<&T> for Spanned<T>
150where
151    T: PartialEq,
152{
153    fn eq(&self, other: &&T) -> bool {
154        (&self.inner as &dyn PartialEq<T>).eq(*other)
155    }
156}
157
158impl<T> Ord for Spanned<T>
159where
160    T: Ord,
161{
162    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
163        Ord::cmp(&self.inner, &other.inner)
164    }
165}
166
167impl<T> PartialOrd for Spanned<T>
168where
169    T: PartialOrd,
170{
171    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
172        PartialOrd::partial_cmp(&self.inner, &other.inner)
173    }
174}
175
176impl<T> PartialOrd<T> for Spanned<T>
177where
178    T: PartialOrd,
179{
180    fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
181        PartialOrd::partial_cmp(&self.inner, other)
182    }
183}
184
185impl<T> Eq for Spanned<T> where T: Eq {}
186
187impl<T> std::hash::Hash for Spanned<T>
188where
189    T: std::hash::Hash,
190{
191    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
192        self.inner.hash(state);
193    }
194}