• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use proc_macro2::Span;
2 
3 /// Exhaustive mirror of [`proc_macro::Level`].
4 #[derive(Debug, Clone)]
5 pub(in crate::error) enum Level {
6     Error,
7     Warning,
8     Note,
9     Help,
10 }
11 
12 /// Supplemental message for an [`Error`](super::Error) when it's emitted as a `Diagnostic`.
13 ///
14 /// # Example Output
15 /// The `note` and `help` lines below come from child diagnostics.
16 ///
17 /// ```text
18 /// error: My custom error
19 ///   --> my_project/my_file.rs:3:5
20 ///    |
21 /// 13 |     FooBar { value: String },
22 ///    |     ^^^^^^
23 ///    |
24 ///    = note: My note on the macro usage
25 ///    = help: Try doing this instead
26 /// ```
27 #[derive(Debug, Clone)]
28 pub(in crate::error) struct ChildDiagnostic {
29     level: Level,
30     span: Option<Span>,
31     message: String,
32 }
33 
34 impl ChildDiagnostic {
new(level: Level, span: Option<Span>, message: String) -> Self35     pub(in crate::error) fn new(level: Level, span: Option<Span>, message: String) -> Self {
36         Self {
37             level,
38             span,
39             message,
40         }
41     }
42 }
43 
44 impl ChildDiagnostic {
45     /// Append this child diagnostic to a `Diagnostic`.
46     ///
47     /// # Panics
48     /// This method panics if `self` has a span and is being invoked outside of
49     /// a proc-macro due to the behavior of [`Span::unwrap()`](Span).
append_to(self, diagnostic: proc_macro::Diagnostic) -> proc_macro::Diagnostic50     pub fn append_to(self, diagnostic: proc_macro::Diagnostic) -> proc_macro::Diagnostic {
51         match self.level {
52             Level::Error => {
53                 if let Some(span) = self.span {
54                     diagnostic.span_error(span.unwrap(), self.message)
55                 } else {
56                     diagnostic.error(self.message)
57                 }
58             }
59             Level::Warning => {
60                 if let Some(span) = self.span {
61                     diagnostic.span_warning(span.unwrap(), self.message)
62                 } else {
63                     diagnostic.warning(self.message)
64                 }
65             }
66             Level::Note => {
67                 if let Some(span) = self.span {
68                     diagnostic.span_note(span.unwrap(), self.message)
69                 } else {
70                     diagnostic.note(self.message)
71                 }
72             }
73             Level::Help => {
74                 if let Some(span) = self.span {
75                     diagnostic.span_help(span.unwrap(), self.message)
76                 } else {
77                     diagnostic.help(self.message)
78                 }
79             }
80         }
81     }
82 }
83