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}