miden_utils_diagnostics/
label.rs

1use alloc::borrow::Cow;
2use core::ops::Range;
3
4use super::LabeledSpan;
5
6/// Represents a diagnostic label.
7///
8/// A label is a source span and optional diagnostic text that should be laid out next to the
9/// source snippet.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Label {
12    span: miette::SourceSpan,
13    label: Option<Cow<'static, str>>,
14}
15
16impl Label {
17    /// Construct a label for the given range of bytes, expressible as any type which can be
18    /// converted to a [`Range<usize>`], e.g. [miette::SourceSpan].
19    pub fn at<R>(range: R) -> Self
20    where
21        Range<usize>: From<R>,
22    {
23        let range = Range::<usize>::from(range);
24        Self { span: range.into(), label: None }
25    }
26
27    /// Construct a label which points to a specific offset in the source file.
28    pub fn point<L>(at: usize, label: L) -> Self
29    where
30        Cow<'static, str>: From<L>,
31    {
32        Self {
33            span: miette::SourceSpan::from(at),
34            label: Some(Cow::from(label)),
35        }
36    }
37
38    /// Construct a label from the given source range and diagnostic text.
39    pub fn new<R, L>(range: R, label: L) -> Self
40    where
41        Range<usize>: From<R>,
42        Cow<'static, str>: From<L>,
43    {
44        let range = Range::<usize>::from(range);
45        Self {
46            span: range.into(),
47            label: Some(Cow::from(label)),
48        }
49    }
50
51    /// Returns the diagnostic text, the actual "label", for this label.
52    pub fn label(&self) -> Option<&str> {
53        self.label.as_deref()
54    }
55}
56
57impl From<Label> for miette::SourceSpan {
58    #[inline(always)]
59    fn from(label: Label) -> Self {
60        label.span
61    }
62}
63
64impl From<Label> for LabeledSpan {
65    #[inline]
66    fn from(label: Label) -> LabeledSpan {
67        if let Some(message) = label.label {
68            LabeledSpan::at(label.span, message)
69        } else {
70            LabeledSpan::underline(label.span)
71        }
72    }
73}