1 | //! A library for formatting compiler error messages, |
2 | //! [extracted from rustc](https://github.com/rust-lang/rust/tree/master/src/librustc_errors) |
3 | //! and built on the types from the [codemap](https://github.com/kevinmehall/codemap) crate. |
4 | //! |
5 | //! # Example |
6 | //! ``` |
7 | //! extern crate codemap; |
8 | //! extern crate codemap_diagnostic; |
9 | //! use codemap::CodeMap; |
10 | //! use codemap_diagnostic::{ Level, SpanLabel, SpanStyle, Diagnostic, ColorConfig, Emitter }; |
11 | //! |
12 | //! fn main() { |
13 | //! let code = "foo + bar" ; |
14 | //! let mut codemap = CodeMap::new(); |
15 | //! let file_span = codemap.add_file("test.rs" .to_owned(), code.to_owned()).span; |
16 | //! let name_span = file_span.subspan(0, 3); |
17 | //! |
18 | //! let label = SpanLabel { |
19 | //! span: name_span, |
20 | //! style: SpanStyle::Primary, |
21 | //! label: Some("undefined variable" .to_owned()) |
22 | //! }; |
23 | //! let d = Diagnostic { |
24 | //! level: Level::Error, |
25 | //! message: "cannot find value `foo` in this scope" .to_owned(), |
26 | //! code: Some("C000" .to_owned()), |
27 | //! spans: vec![label] |
28 | //! }; |
29 | //! |
30 | //! let mut emitter = Emitter::stderr(ColorConfig::Always, Some(&codemap)); |
31 | //! emitter.emit(&[d]); |
32 | //! } |
33 | //! ``` |
34 | |
35 | extern crate termcolor; |
36 | extern crate codemap; |
37 | |
38 | use codemap::Span; |
39 | |
40 | mod lock; |
41 | mod snippet; |
42 | mod styled_buffer; |
43 | mod emitter; |
44 | |
45 | pub use emitter::{ ColorConfig, Emitter }; |
46 | use termcolor::{ ColorSpec, Color }; |
47 | |
48 | /// A diagnostic message. |
49 | #[derive (Clone, Debug, PartialEq, Eq)] |
50 | pub struct Diagnostic { |
51 | /// The severity of the message, used to set color scheme |
52 | pub level: Level, |
53 | |
54 | /// Message used as the headline of the error |
55 | pub message: String, |
56 | |
57 | /// A short error number or code |
58 | pub code: Option<String>, |
59 | |
60 | /// Locations to underline in the code |
61 | pub spans: Vec<SpanLabel>, |
62 | } |
63 | |
64 | /// A level representing the severity of a Diagnostic. |
65 | /// |
66 | /// These result in different output styling. |
67 | #[derive (Copy, Clone, PartialEq, Eq, Debug)] |
68 | pub enum Level { |
69 | Bug, |
70 | Error, |
71 | Warning, |
72 | Note, |
73 | Help, |
74 | } |
75 | |
76 | impl ::std::fmt::Display for Level { |
77 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { |
78 | self.to_str().fmt(f) |
79 | } |
80 | } |
81 | |
82 | impl Level { |
83 | fn color(self) -> ColorSpec { |
84 | let mut spec = ColorSpec::new(); |
85 | use self::Level::*; |
86 | match self { |
87 | Bug | Error => { |
88 | spec.set_fg(Some(Color::Red)) |
89 | .set_intense(true); |
90 | } |
91 | Warning => { |
92 | spec.set_fg(Some(Color::Yellow)) |
93 | .set_intense(cfg!(windows)); |
94 | } |
95 | Note => { |
96 | spec.set_fg(Some(Color::Green)) |
97 | .set_intense(true); |
98 | } |
99 | Help => { |
100 | spec.set_fg(Some(Color::Cyan)) |
101 | .set_intense(true); |
102 | } |
103 | } |
104 | spec |
105 | } |
106 | |
107 | pub fn to_str(self) -> &'static str { |
108 | use self::Level::*; |
109 | |
110 | match self { |
111 | Bug => "error: internal compiler error" , |
112 | Error => "error" , |
113 | Warning => "warning" , |
114 | Note => "note" , |
115 | Help => "help" , |
116 | } |
117 | } |
118 | } |
119 | |
120 | /// A labeled region of the code related to a Diagnostic. |
121 | #[derive (Clone, Debug, PartialEq, Eq)] |
122 | pub struct SpanLabel { |
123 | /// The location in the code. |
124 | /// |
125 | /// This Span must come from the same CodeMap used to construct the Emitter. |
126 | pub span: Span, |
127 | |
128 | /// A label used to provide context for the underlined code. |
129 | pub label: Option<String>, |
130 | |
131 | /// A style used to set the character used for the underline. |
132 | pub style: SpanStyle, |
133 | } |
134 | |
135 | /// Underline style for a SpanLabel. |
136 | #[derive (Copy, Clone, PartialEq, Eq, Debug)] |
137 | pub enum SpanStyle { |
138 | Primary, |
139 | Secondary, |
140 | } |
141 | |