friendly_errors/
lib.rs

1pub use code_snippet::{FriendlyCodeSnippet, FriendlyCodeSnippetError};
2
3mod code_snippet;
4mod description;
5mod doc_url;
6mod header;
7mod print_snippets;
8mod summary;
9
10#[derive(PartialEq, Debug, Clone)]
11pub enum ErrorKind {
12    Error,
13    Warning,
14    Improvement,
15    CodeStyle,
16}
17
18#[derive(PartialEq, Debug, Clone)]
19struct ErrorData {
20    code_snippets: Vec<FriendlyCodeSnippet>,
21    description: Option<String>,
22    doc_url: Option<String>,
23    error_code: Option<String>,
24    kind: ErrorKind,
25    summary: Option<String>,
26    title: Option<String>,
27}
28
29pub struct FriendlyError {
30    data: ErrorData,
31    pub(crate) output: String,
32}
33
34#[derive(PartialEq, Debug, Clone)]
35pub enum FriendlyErrorError {
36    CodeSnippetError(FriendlyCodeSnippetError),
37}
38
39pub type FriendlyErrorResult = Result<String, FriendlyErrorError>;
40
41impl FriendlyError {
42    pub fn new() -> Self {
43        FriendlyError {
44            data: {
45                ErrorData {
46                    code_snippets: Vec::new(),
47                    description: None,
48                    doc_url: None,
49                    error_code: None,
50                    kind: ErrorKind::Error,
51                    summary: None,
52                    title: None,
53                }
54            },
55            output: String::new(),
56        }
57    }
58
59    pub fn add_code_snippet(mut self, code_snippet: FriendlyCodeSnippet) -> Self {
60        self.data.code_snippets.push(code_snippet);
61        self
62    }
63
64    pub fn description<S: Into<String>>(mut self, description: S) -> Self {
65        self.data.description = Some(description.into());
66        self
67    }
68
69    pub fn doc_url<S: Into<String>>(mut self, url: S) -> Self {
70        self.data.doc_url = Some(url.into());
71        self
72    }
73
74    pub fn error_code<S: Into<String>>(mut self, code: S) -> Self {
75        self.data.error_code = Some(code.into());
76        self
77    }
78
79    pub fn kind(mut self, kind: ErrorKind) -> Self {
80        self.data.kind = kind;
81        self
82    }
83
84    pub fn summary<S: Into<String>>(mut self, summary: S) -> Self {
85        self.data.summary = Some(summary.into());
86        self
87    }
88
89    pub fn title<S: Into<String>>(mut self, title: S) -> Self {
90        self.data.title = Some(title.into());
91        self
92    }
93
94    pub fn build(mut self) -> FriendlyErrorResult {
95        self.print_header();
96        self.print_summary();
97        self.print_code_snippets()?;
98        self.print_description();
99        self.print_doc_url();
100        Ok(self.output)
101    }
102
103    #[cfg(test)]
104    pub(crate) fn set_output<S: Into<String>>(mut self, output: S) -> Self {
105        self.output = output.into();
106        self
107    }
108
109    pub(crate) fn add_empty_line(&mut self) {
110        if !self.output.is_empty() {
111            self.output.push('\n');
112            self.output.push('\n');
113        }
114    }
115}
116
117impl Default for FriendlyError {
118    fn default() -> Self {
119        Self::new()
120    }
121}