Skip to main content

error_enum_core/
span.rs

1use crate::{Indexer, LineIndexer};
2use alloc::sync::Arc;
3use core::{fmt, ops::Range};
4
5/// Trait for span types used in error enums.
6pub trait Span: Clone {
7    /// The URI type for the span.
8    type Uri: PartialEq + Clone + fmt::Display;
9    /// The source text type for the span.
10    type Source: AsRef<str> + Clone;
11    /// The index of the source text.
12    type Index: Indexer + ?Sized;
13
14    /// Get the start position of the span.
15    fn start(&self) -> usize;
16    /// Get the end position of the span.
17    fn end(&self) -> usize;
18    /// Get the range of the span.
19    fn range(&self) -> Range<usize> {
20        self.start()..self.end()
21    }
22    /// Get the source text of the span.
23    fn source_text(&self) -> &Self::Source;
24    /// Get the index of the source.
25    fn source_index(&self) -> &Self::Index;
26    /// Get the URI of the span.
27    fn uri(&self) -> &Self::Uri;
28}
29
30/// A simple implementation of [`Span`].
31#[derive(Clone, Debug, PartialEq, Eq)]
32pub struct SimpleSpan {
33    uri: Arc<str>,
34    source: Arc<str>,
35    indexer: Arc<LineIndexer>,
36    start: usize,
37    end: usize,
38}
39
40impl SimpleSpan {
41    /// Create a new [`SimpleSpan`].
42    pub fn new(
43        uri: impl Into<Arc<str>>,
44        source: impl Into<Arc<str>>,
45        start: usize,
46        end: usize,
47    ) -> Self {
48        let uri = uri.into();
49        let source = source.into();
50        let indexer = LineIndexer::new(&source).into();
51        Self {
52            uri,
53            source,
54            indexer,
55            start,
56            end,
57        }
58    }
59}
60
61impl Span for SimpleSpan {
62    type Uri = Arc<str>;
63    type Source = Arc<str>;
64    type Index = Arc<LineIndexer>;
65
66    fn start(&self) -> usize {
67        self.start
68    }
69    fn end(&self) -> usize {
70        self.end
71    }
72    fn source_text(&self) -> &Self::Source {
73        &self.source
74    }
75    fn source_index(&self) -> &Self::Index {
76        &self.indexer
77    }
78    fn uri(&self) -> &Self::Uri {
79        &self.uri
80    }
81}
82
83impl Default for SimpleSpan {
84    fn default() -> Self {
85        Self::new("", "", 0, 0)
86    }
87}
88
89impl From<&SimpleSpan> for SimpleSpan {
90    fn from(value: &SimpleSpan) -> Self {
91        value.clone()
92    }
93}