1use std::path::PathBuf;
4
5#[derive(Clone, Debug)]
8pub struct Context {
9 pub path: Option<PathBuf>,
10 pub content: Option<String>,
11
12 pub line_index: Option<usize>,
17 pub column_index: Option<usize>,
18}
19
20impl Context {
21 pub fn new() -> Self {
22 Self {
23 path: None,
24 content: None,
25 line_index: None,
26 column_index: None,
27 }
28 }
29
30 pub fn label(&self) -> Option<String> {
31 let Some(path_display) = self.path.as_ref().map(|p| p.display() ) else {
32 return None;
33 };
34
35 return match self.line_index {
38 Some(line) => match self.column_index {
39 Some(column) => Some(format!("{}:{}:{}", path_display, line + 1, column + 1)),
40 None => Some(format!("{}:{}", path_display, line + 1)),
41 },
42 None => Some(path_display.to_string()),
43 };
44 }
45
46 pub fn display_line(&self) -> Option<String> {
47 self.content.as_ref().map(|content| match self.line_index {
48 Some(line) => {
49 let line_s = (line + 1).to_string();
50 let pad = " ".repeat(line_s.len());
51
52 match self.column_index {
53 Some(column) => format!(
54 "{pad} |\n{line_number} | {content}\n{pad} | {caret_padding}^\n",
55 pad = pad,
56 line_number = line_s,
57 content = content,
58 caret_padding = " ".repeat(column),
59 ),
60 None => format!(
61 "{pad} |\n{line_number} | {content}\n{pad} | \n",
62 pad = pad,
63 line_number = line_s,
64 content = content,
65 ),
66 }
67 }
68 None => format!(" | {content}\n", content = content),
69 })
70 }
71}
72
73impl From<PathBuf> for Context {
74 fn from(path: PathBuf) -> Self {
75 let mut context = Self::new();
76 context.path = Some(path);
77 context
78 }
79}