lwb_parser/sources/
span.rs1use crate::sources::source_file::SourceFile;
2use miette::{MietteError, SourceCode, SourceSpan, SpanContents};
3use serde::{Deserialize, Serialize};
4use std::fmt::{Debug, Formatter};
5
6#[derive(Clone, Serialize, Deserialize)]
9pub struct Span {
10 pub position: usize,
11 pub length: usize,
12 pub source: SourceFile,
13}
14
15impl Debug for Span {
16 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17 f.debug_struct("Span")
18 .field("position", &self.position)
19 .field("length", &self.length)
20 .finish()
21 }
22}
23
24impl Span {
25 pub fn from_length(source: &SourceFile, position: usize, length: usize) -> Self {
27 Self {
28 source: source.clone(),
29 position,
30 length,
31 }
32 }
33
34 pub fn from_end(source: &SourceFile, position: usize, end: usize) -> Self {
36 assert!(end >= position);
37 Self {
38 source: source.clone(),
39 position,
40 length: end - position,
41 }
42 }
43
44 pub fn end(&self) -> usize {
45 self.position + self.length
46 }
47
48 pub fn as_str(&self) -> &str {
53 &self.source.contents()[self.position..self.position + self.length]
54 }
55
56 pub fn merge(&self, other: &Span) -> Self {
58 Self::from_end(
62 &self.source,
63 self.position.min(other.position),
64 self.end().max(other.end()),
65 )
66 }
67}
68
69impl SourceCode for Span {
70 fn read_span<'a>(
71 &'a self,
72 span: &SourceSpan,
73 context_lines_before: usize,
74 context_lines_after: usize,
75 ) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError> {
76 <str as SourceCode>::read_span(
77 self.source.contents_for_display(),
78 span,
79 context_lines_before,
80 context_lines_after,
81 )
82 }
83}
84
85impl From<Span> for SourceSpan {
86 fn from(span: Span) -> Self {
87 SourceSpan::from((span.position, span.length))
88 }
89}