codemap2_diagnostic/
lib.rs

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 codemap2;
8//! extern crate codemap2_diagnostic;
9//! use codemap2::{CodeMap, DefaultFileData};
10//! use codemap2_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(DefaultFileData::new("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
35extern crate termcolor;
36pub extern crate codemap2;
37extern crate atty;
38
39pub use codemap2::*;
40
41mod lock;
42mod snippet;
43mod styled_buffer;
44mod emitter;
45
46pub use emitter::{ ColorConfig, Emitter };
47use termcolor::{ ColorSpec, Color };
48
49/// A diagnostic message.
50#[derive(Clone, Debug, PartialEq, Eq)]
51pub struct Diagnostic {
52    /// The severity of the message, used to set color scheme
53    pub level: Level,
54
55    /// Message used as the headline of the error
56    pub message: String,
57
58    /// A short error number or code
59    pub code: Option<String>,
60
61    /// Locations to underline in the code
62    pub spans: Vec<SpanLabel>,
63}
64
65/// A level representing the severity of a Diagnostic.
66///
67/// These result in different output styling.
68#[derive(Copy, Clone, PartialEq, Eq, Debug)]
69pub enum Level {
70    Bug,
71    Error,
72    Warning,
73    Note,
74    Help,
75}
76
77impl ::std::fmt::Display for Level {
78    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
79        self.to_str().fmt(f)
80    }
81}
82
83impl Level {
84    fn color(self) -> ColorSpec {
85        let mut spec = ColorSpec::new();
86        use self::Level::*;
87        match self {
88            Bug | Error => {
89                spec.set_fg(Some(Color::Red))
90                    .set_intense(true);
91            }
92            Warning => {
93                spec.set_fg(Some(Color::Yellow))
94                    .set_intense(cfg!(windows));
95            }
96            Note => {
97                spec.set_fg(Some(Color::Green))
98                    .set_intense(true);
99            }
100            Help => {
101                spec.set_fg(Some(Color::Cyan))
102                    .set_intense(true);
103            }
104        }
105        spec
106    }
107
108    pub fn to_str(self) -> &'static str {
109        use self::Level::*;
110
111        match self {
112            Bug => "error: internal compiler error",
113            Error => "error",
114            Warning => "warning",
115            Note => "note",
116            Help => "help",
117        }
118    }
119}
120
121/// A labeled region of the code related to a Diagnostic.
122#[derive(Clone, Debug, PartialEq, Eq)]
123pub struct SpanLabel {
124    /// The location in the code.
125    ///
126    /// This Span must come from the same CodeMap used to construct the Emitter.
127    pub span: Span,
128
129    /// A label used to provide context for the underlined code.
130    pub label: Option<String>,
131
132    /// A style used to set the character used for the underline.
133    pub style: SpanStyle,
134}
135
136/// Underline style for a SpanLabel.
137#[derive(Copy, Clone, PartialEq, Eq, Debug)]
138pub enum SpanStyle {
139    Primary,
140    Secondary,
141}