1use crate::report::{
8 Confidence, ErrorKey, ErrorLoc, LogReportMetadata, LogReportPointers, LogReportStyle,
9 PointedMessage, Severity, log,
10};
11
12pub fn tips(key: ErrorKey) -> ReportBuilderStage1 {
17 ReportBuilderStage1::new(key, Severity::Tips)
18}
19
20pub fn untidy(key: ErrorKey) -> ReportBuilderStage1 {
21 ReportBuilderStage1::new(key, Severity::Untidy)
22}
23
24pub fn warn(key: ErrorKey) -> ReportBuilderStage1 {
25 ReportBuilderStage1::new(key, Severity::Warning)
26}
27
28pub fn err(key: ErrorKey) -> ReportBuilderStage1 {
29 ReportBuilderStage1::new(key, Severity::Error)
30}
31
32pub fn fatal(key: ErrorKey) -> ReportBuilderStage1 {
33 ReportBuilderStage1::new(key, Severity::Fatal)
34}
35
36pub fn report(key: ErrorKey, severity: Severity) -> ReportBuilderStage1 {
37 ReportBuilderStage1::new(key, severity)
38}
39
40#[derive(Debug, Clone, Copy)]
45#[must_use]
46pub struct ReportBuilderStage1(ErrorKey, Severity, Confidence);
47
48impl ReportBuilderStage1 {
49 fn new(key: ErrorKey, severity: Severity) -> Self {
51 Self(key, severity, Confidence::Reasonable)
52 }
53
54 pub fn weak(mut self) -> Self {
56 self.2 = Confidence::Weak;
57 self
58 }
59
60 pub fn strong(mut self) -> Self {
62 self.2 = Confidence::Strong;
63 self
64 }
65
66 pub fn conf(mut self, conf: Confidence) -> Self {
68 self.2 = conf;
69 self
70 }
71
72 pub fn msg<S: Into<String>>(self, msg: S) -> ReportBuilderStage2 {
74 ReportBuilderStage2 { stage1: self, msg: msg.into(), info: None, wiki: None }
75 }
76}
77
78#[derive(Debug)]
79#[must_use]
80pub struct ReportBuilderStage2 {
81 stage1: ReportBuilderStage1,
82 msg: String,
83 info: Option<String>,
84 wiki: Option<String>,
85}
86
87impl ReportBuilderStage2 {
88 pub fn info<S: Into<String>>(mut self, info: S) -> Self {
90 let info = info.into();
91 self.info = if info.is_empty() { None } else { Some(info) };
92 self
93 }
94
95 pub fn opt_info<S: Into<String>>(mut self, info: Option<S>) -> Self {
97 self.info = info.map(Into::into);
98 self
99 }
100
101 #[allow(dead_code)]
103 pub fn wiki<S: Into<String>>(mut self, wiki: S) -> Self {
104 let wiki = wiki.into();
105 self.wiki = if wiki.is_empty() { None } else { Some(wiki) };
106 self
107 }
108
109 pub fn loc<E: ErrorLoc>(self, eloc: E) -> ReportBuilderFull {
110 let length = eloc.loc_length();
111 ReportBuilderFull {
112 stage1: self.stage1,
113 msg: self.msg,
114 info: self.info,
115 wiki: self.wiki,
116 pointers: vec![PointedMessage { loc: eloc.into_loc(), length, msg: None }],
117 }
118 }
119
120 pub fn loc_msg<E: ErrorLoc, S: Into<String>>(self, eloc: E, msg: S) -> ReportBuilderFull {
121 let length = eloc.loc_length();
122 ReportBuilderFull {
123 stage1: self.stage1,
124 msg: self.msg,
125 info: self.info,
126 wiki: self.wiki,
127 pointers: vec![PointedMessage { loc: eloc.into_loc(), length, msg: Some(msg.into()) }],
128 }
129 }
130
131 pub fn pointers(self, pointers: LogReportPointers) -> ReportBuilderFull {
132 ReportBuilderFull {
133 stage1: self.stage1,
134 msg: self.msg,
135 info: self.info,
136 wiki: self.wiki,
137 pointers,
138 }
139 }
140
141 pub fn abbreviated<E: ErrorLoc>(self, eloc: E) -> ReportBuilderAbbreviated {
142 ReportBuilderAbbreviated {
143 stage1: self.stage1,
144 msg: self.msg,
145 info: self.info,
146 wiki: self.wiki,
147 pointers: vec![PointedMessage { loc: eloc.into_loc(), length: 0, msg: None }],
148 }
149 }
150}
151
152#[derive(Debug)]
153#[must_use]
154pub struct ReportBuilderFull {
155 stage1: ReportBuilderStage1,
156 msg: String,
157 info: Option<String>,
158 wiki: Option<String>,
159 pointers: LogReportPointers,
160}
161
162impl ReportBuilderFull {
163 pub fn loc_msg<E: ErrorLoc, S: Into<String>>(mut self, eloc: E, msg: S) -> Self {
164 let length = eloc.loc_length();
165 self.pointers.push(PointedMessage { loc: eloc.into_loc(), length, msg: Some(msg.into()) });
166 self
167 }
168 pub fn opt_loc_msg<E: ErrorLoc, S: Into<String>>(mut self, eloc: Option<E>, msg: S) -> Self {
169 if let Some(eloc) = eloc {
170 let length = eloc.loc_length();
171 self.pointers.push(PointedMessage {
172 loc: eloc.into_loc(),
173 length,
174 msg: Some(msg.into()),
175 });
176 }
177 self
178 }
179 pub fn build(self) -> (LogReportMetadata, LogReportPointers) {
181 (
182 LogReportMetadata {
183 key: self.stage1.0,
184 severity: self.stage1.1,
185 confidence: self.stage1.2,
186 msg: self.msg,
187 info: self.info,
188 wiki: self.wiki,
189 style: LogReportStyle::Full,
190 },
191 self.pointers,
192 )
193 }
194 pub fn push(self) {
196 log(self.build());
197 }
198}
199
200#[derive(Debug)]
201#[must_use]
202pub struct ReportBuilderAbbreviated {
203 stage1: ReportBuilderStage1,
204 msg: String,
205 info: Option<String>,
206 wiki: Option<String>,
207 pointers: LogReportPointers,
208}
209
210impl ReportBuilderAbbreviated {
211 pub fn build(self) -> (LogReportMetadata, LogReportPointers) {
213 (
214 LogReportMetadata {
215 key: self.stage1.0,
216 severity: self.stage1.1,
217 confidence: self.stage1.2,
218 msg: self.msg,
219 info: self.info,
220 wiki: self.wiki,
221 style: LogReportStyle::Abbreviated,
222 },
223 self.pointers,
224 )
225 }
226 pub fn push(self) {
228 log(self.build());
229 }
230}