1use std::{
2 fmt::Display,
3 path::{Path, PathBuf},
5};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct RawLoc {
10 pub filename: PathBuf,
11 pub lines: Vec<u32>, }
13
14impl RawLoc {
15 pub fn new(filename: PathBuf, lines: Vec<u32>) -> Self {
17 Self { filename, lines }
18 }
19}
20
21#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
23pub struct Loc(PathBuf, String);
24
25impl Loc {
26 pub fn path(&self) -> &PathBuf {
28 &self.0
29 }
30
31 pub fn fn_name(&self) -> &str {
33 self.1.split("::").last().unwrap_or("")
34 }
35
36 pub fn full_fn_name(&self) -> &str {
38 &self.1
39 }
40
41 pub fn file_name(&self) -> String {
43 let split_str = self.1.split("::");
44 let mut split_as_vec = split_str.collect::<Vec<&str>>();
45 split_as_vec.pop();
46 split_as_vec.join("::")
47 }
48
49 pub fn read_source<S: FileSystem>(&self, fs: &S) -> Result<String, S::FSError> {
51 fs.read(&self.0)
52 }
53
54 pub fn write_source<S: FileSystem>(&self, fs: &S, str: &str) -> Result<(), S::FSError> {
56 fs.write(&self.0, str.as_bytes())
57 }
58}
59
60impl Display for Loc {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(f, "{}:{}", self.0.to_str().unwrap_or(""), self.1)
63 }
64}
65
66impl From<(RawLoc, String)> for Loc {
67 fn from((loc, name): (RawLoc, String)) -> Self {
68 Loc(loc.filename, name)
69 }
70}
71
72pub trait FileSystem: Clone {
74 type FSError: std::fmt::Debug;
75
76 fn exists<P: AsRef<Path>>(&self, path: P) -> Result<bool, Self::FSError>;
77 fn read<P: AsRef<Path>>(&self, filename: P) -> Result<String, Self::FSError>;
78 fn write<P: AsRef<Path>, C: AsRef<[u8]>>(
79 &self,
80 filename: P,
81 contents: C,
82 ) -> Result<(), Self::FSError>;
83}