tiger_lib/report/report_struct.rs
1use serde::Serialize;
2use strum_macros::{Display, EnumCount, EnumIter, EnumString, IntoStaticStr};
3
4use crate::report::ErrorKey;
5use crate::token::Loc;
6
7pub type LogReport = (LogReportMetadata, LogReportPointers);
8
9#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
10pub enum LogReportStyle {
11 Full,
12 Abbreviated,
13}
14
15/// Describes a report about a potentially problematic situation that can be logged.
16#[derive(Debug, Clone, Hash, PartialEq, Eq)]
17pub struct LogReportMetadata {
18 /// Used for choosing output colors and for filtering reports.
19 pub severity: Severity,
20 /// Mostly used for filtering reports.
21 pub confidence: Confidence,
22 /// Defines the problem category. Used for filtering reports.
23 pub key: ErrorKey,
24 /// The primary error message. A short description of the problem.
25 pub msg: String,
26 /// Optional info message to be printed at the end.
27 pub info: Option<String>,
28 /// Optional wiki link to be printed at the end.
29 pub wiki: Option<String>,
30 // /// Output style for this report
31 pub style: LogReportStyle,
32}
33
34#[derive(Debug, Clone, Hash, PartialEq, Eq)]
35pub struct PointedMessage {
36 /// Which file and where in the file the error occurs.
37 /// Might point to a whole file, rather than a specific location in the file.
38 pub loc: Loc,
39 /// The length of the offending phrase in characters.
40 /// Set this to 1 if the length cannot be determined.
41 /// This will determine the number of carets that are printed at the given location.
42 /// e.g.: ^^^^^^^^^
43 /// A length of 0 will hide the carets
44 /// TODO: If we end up adding length to Loc, this field can be deleted.
45 pub length: usize,
46 /// A short message that will be printed at the caret location.
47 pub msg: Option<String>,
48}
49
50impl PointedMessage {
51 pub fn new(loc: Loc) -> Self {
52 Self { loc, msg: None, length: 0 }
53 }
54}
55
56/// Should contain one or more elements.
57pub type LogReportPointers = Vec<PointedMessage>;
58
59pub fn pointer_indentation(pointers: &LogReportPointers) -> usize {
60 pointers.iter().map(|pointer| pointer.loc.line.to_string().len()).max().unwrap_or(0)
61}
62
63/// Determines the output colour.
64/// User can also filter by minimum severity level: e.g. don't show me Info-level messages.
65///
66/// The order of these enum values determines the level of severity they denote.
67/// Do not change the order unless you mean to change the logic of the program!
68#[derive(
69 Default,
70 Debug,
71 Display,
72 Clone,
73 Copy,
74 Ord,
75 PartialOrd,
76 Eq,
77 PartialEq,
78 Hash,
79 IntoStaticStr,
80 EnumString,
81 EnumCount,
82 EnumIter,
83 Serialize,
84)]
85#[serde(rename_all = "kebab-case")]
86#[strum(serialize_all = "kebab-case")]
87pub enum Severity {
88 /// These are things that aren't necessarily wrong, but there may be a better, more
89 /// idiomatic way to do it. This may also include performance issues.
90 Tips,
91 /// This code smells.
92 /// The player is unlikely to be impacted directly, but developers working on this codebase
93 /// will likely experience maintenance headaches.
94 Untidy,
95 /// This will result in glitches that will noticeably impact the player's gaming experience.
96 /// Missing translations are an example.
97 #[default]
98 Warning,
99 /// This code probably doesn't work as intended. The player may experience bugs.
100 Error,
101 /// This is likely to cause crashes.
102 Fatal,
103}
104
105impl Severity {
106 /// Reduce the severity to at most `max_sev`, unless severity is `Fatal`, then stays `Fatal`.
107 #[must_use]
108 pub fn at_most(self, max_sev: Severity) -> Severity {
109 if self == Severity::Fatal {
110 Severity::Fatal
111 } else {
112 self.min(max_sev)
113 }
114 }
115}
116
117/// Mostly invisible in the output.
118/// User can filter by minimum confidence level.
119/// This would be a dial for how many false positives they're willing to put up with.
120///
121/// The order of these enum values determines the level of confidence they denote.
122/// Do not change the order unless you mean to change the logic of the program!
123#[derive(
124 Default,
125 Debug,
126 Clone,
127 Copy,
128 Ord,
129 PartialOrd,
130 Eq,
131 PartialEq,
132 Hash,
133 IntoStaticStr,
134 EnumIter,
135 EnumString,
136 Serialize,
137)]
138#[serde(rename_all = "kebab-case")]
139#[strum(serialize_all = "kebab-case")]
140pub enum Confidence {
141 /// Quite likely to be a false positive.
142 Weak,
143 /// Reasonably confident that the problem is real.
144 #[default]
145 Reasonable,
146 /// Very confident that this problem is real.
147 Strong,
148}