1use std::{ops::Range, path::Path, sync::Arc};
2
3use crate::LineCol;
4
5#[derive(Debug, Clone)]
6pub struct Source {
7 pub text: Arc<str>,
8 pub kind: SourceKind,
9}
10
11impl Source {
12 pub fn new(text: Arc<str>, kind: SourceKind) -> Self {
13 Self { text, kind }
14 }
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub enum SourceKind {
19 Std(String),
20 File(String),
21}
22
23impl SourceKind {
24 pub fn check_unused(&self) -> bool {
25 match self {
26 Self::Std(_) => false,
27 Self::File(_) => true,
28 }
29 }
30
31 pub fn display(&self, relative_to: &Path) -> String {
32 match self {
33 Self::Std(path) => Path::new("std").join(path).to_string_lossy().to_string(),
34 Self::File(path) => Path::new(path)
35 .strip_prefix(relative_to)
36 .map_or_else(|_| path.clone(), |path| path.to_string_lossy().to_string()),
37 }
38 }
39}
40
41#[derive(Debug, Clone)]
42pub struct SrcLoc {
43 pub source: Source,
44 pub span: Range<usize>,
45}
46
47impl SrcLoc {
48 pub fn new(source: Source, span: Range<usize>) -> Self {
49 Self { source, span }
50 }
51
52 pub fn start(&self) -> LineCol {
53 LineCol::new(&self.source.text, self.span.start)
54 }
55
56 pub fn end(&self) -> LineCol {
57 LineCol::new(&self.source.text, self.span.end)
58 }
59
60 pub fn display(&self, relative_to: &Path) -> String {
61 format!("{}:{}", self.source.kind.display(relative_to), self.start())
62 }
63}