dfir_lang/
pretty_span.rs
1use std::path::Path;
4
5extern crate proc_macro;
6
7pub struct PrettySpan(pub proc_macro2::Span);
10impl std::fmt::Display for PrettySpan {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 #[cfg(nightly)]
13 if proc_macro::is_available() {
14 use std::path::MAIN_SEPARATOR;
15
16 let span = self.0.unwrap();
17
18 let path = span.file();
19 let path = make_source_path_relative(&path);
20 let mut path_str = path.display().to_string();
21 if '/' != MAIN_SEPARATOR && path.is_relative() {
22 path_str = path_str.replace(MAIN_SEPARATOR, "/");
24 }
25
26 write!(
27 f,
28 "{}:{}:{}",
29 path_str,
30 span.start().line(),
31 span.start().column(),
32 )?;
33 return Ok(());
34 }
35
36 write!(
37 f,
38 "unknown:{}:{}",
39 self.0.start().line,
40 self.0.start().column
41 )
42 }
43}
44
45pub struct PrettyRowCol(pub proc_macro2::Span);
47impl std::fmt::Display for PrettyRowCol {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 let span = self.0;
50 write!(f, "{}:{}", span.start().line, span.start().column)
51 }
52}
53
54pub fn make_source_path_relative(source_path: &impl AsRef<Path>) -> &Path {
56 let source_path = source_path.as_ref();
57 std::env::var_os("DFIR_BASE_DIR")
58 .and_then(|base_dir| source_path.strip_prefix(base_dir).ok())
59 .or_else(|| {
60 let manifest_dir = std::env::var_os("CARGO_MANIFEST_DIR")?;
61 source_path.strip_prefix(manifest_dir).ok()
62 })
63 .unwrap_or(source_path)
64}