Preserve warning display rework, but without breaking the LSP quickfixes.
This commit is contained in:
parent
649e5163fc
commit
e9e26b969a
|
@ -1475,31 +1475,29 @@ fn suggest_import_constructor() -> String {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, thiserror::Error, Diagnostic)]
|
#[derive(Debug, PartialEq, Clone, thiserror::Error, Diagnostic)]
|
||||||
pub enum Warning {
|
pub enum Warning {
|
||||||
#[error("I found a record update using all fields; thus redundant.\n")]
|
#[error("I found a record update using all fields; thus redundant.")]
|
||||||
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types#record-updates"))]
|
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types#record-updates"))]
|
||||||
#[diagnostic(code("record_update::all_fields"))]
|
#[diagnostic(code("record_update::all_fields"))]
|
||||||
AllFieldsRecordUpdate {
|
AllFieldsRecordUpdate {
|
||||||
#[label]
|
#[label("redundant record update")]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error("I realized the following expression returned a result that is implicitly discarded.")]
|
||||||
"I realized the following expression returned a result that is implicitly discarded.\n"
|
|
||||||
)]
|
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"You can use the '_' symbol should you want to explicitly discard a result."
|
"You can use the '_' symbol should you want to explicitly discard a result."
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("implicit_discard"))]
|
#[diagnostic(code("implicit_discard"))]
|
||||||
ImplicitlyDiscardedResult {
|
ImplicitlyDiscardedResult {
|
||||||
#[label]
|
#[label("implicitly discarded result")]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I found a record update with no fields; effectively updating nothing.\n")]
|
#[error("I found a record update with no fields; effectively updating nothing.")]
|
||||||
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types#record-updates"))]
|
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types#record-updates"))]
|
||||||
#[diagnostic(code("record_update::no_fields"))]
|
#[diagnostic(code("record_update::no_fields"))]
|
||||||
NoFieldsRecordUpdate {
|
NoFieldsRecordUpdate {
|
||||||
#[label]
|
#[label("useless record update")]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1519,17 +1517,20 @@ pub enum Warning {
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I found an {} trying to match a type with one constructor",
|
"I found an {} {}",
|
||||||
"expect".if_supports_color(Stderr, |s| s.purple())
|
"expect".if_supports_color(Stderr, |s| s.purple()),
|
||||||
|
"trying to match a type with one constructor".if_supports_color(Stderr, |s| s.yellow())
|
||||||
)]
|
)]
|
||||||
#[diagnostic(
|
#[diagnostic(
|
||||||
code("single_constructor_expect"),
|
code("single_constructor_expect"),
|
||||||
help(
|
help(
|
||||||
"If your type has one constructor, unless you are casting {} {}, you can\nprefer using a {} binding like so...\n\n{}",
|
"If your type has one constructor, unless you are casting {} {}, you can\nprefer using a {} binding like so...\n\n{}",
|
||||||
"from".if_supports_color(Stderr, |s| s.bold()),
|
"from".if_supports_color(Stderr, |s| s.bold()),
|
||||||
"Data".if_supports_color(Stderr, |s| s.bright_blue()),
|
"Data"
|
||||||
|
.if_supports_color(Stderr, |s| s.bold())
|
||||||
|
.if_supports_color(Stderr, |s| s.bright_blue()),
|
||||||
"let".if_supports_color(Stderr, |s| s.purple()),
|
"let".if_supports_color(Stderr, |s| s.purple()),
|
||||||
format_suggestion(sample)
|
format_suggestion(sample),
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
SingleConstructorExpect {
|
SingleConstructorExpect {
|
||||||
|
@ -1542,7 +1543,7 @@ pub enum Warning {
|
||||||
sample: UntypedExpr,
|
sample: UntypedExpr,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I found a todo left in the code.\n")]
|
#[error("I found a todo left in the code.")]
|
||||||
#[diagnostic(help("You probably want to replace that with actual code... eventually."))]
|
#[diagnostic(help("You probably want to replace that with actual code... eventually."))]
|
||||||
#[diagnostic(code("todo"))]
|
#[diagnostic(code("todo"))]
|
||||||
Todo {
|
Todo {
|
||||||
|
@ -1551,7 +1552,7 @@ pub enum Warning {
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I found a type hole in an annotation.\n")]
|
#[error("I found a type hole in an annotation.")]
|
||||||
#[diagnostic(code("unexpected::type_hole"))]
|
#[diagnostic(code("unexpected::type_hole"))]
|
||||||
UnexpectedTypeHole {
|
UnexpectedTypeHole {
|
||||||
#[label("{}", tipo.to_pretty(0))]
|
#[label("{}", tipo.to_pretty(0))]
|
||||||
|
@ -1560,93 +1561,95 @@ pub enum Warning {
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I discovered an unused constructor: '{}'.\n",
|
"I discovered an unused constructor: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name.if_supports_color(Stderr, |s| s.default_color())
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"No big deal, but you might want to remove it to get rid of that warning."
|
"No big deal, but you might want to remove it to get rid of that warning."
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused::constructor"))]
|
#[diagnostic(code("unused::constructor"))]
|
||||||
UnusedConstructor {
|
UnusedConstructor {
|
||||||
#[label]
|
#[label("unused constructor")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I discovered an unused imported module: '{}'.\n",
|
"I discovered an unused imported module: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name.if_supports_color(Stderr, |s| s.default_color()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"No big deal, but you might want to remove it to get rid of that warning."
|
"No big deal, but you might want to remove it to get rid of that warning."
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused::import::module"))]
|
#[diagnostic(code("unused::import::module"))]
|
||||||
UnusedImportedModule {
|
UnusedImportedModule {
|
||||||
#[label]
|
#[label("unused module")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I discovered an unused imported value: '{}'.\n",
|
"I discovered an unused imported value: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple()),
|
name.if_supports_color(Stderr, |s| s.default_color()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"No big deal, but you might want to remove it to get rid of that warning."
|
"No big deal, but you might want to remove it to get rid of that warning."
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused:import::value"))]
|
#[diagnostic(code("unused:import::value"))]
|
||||||
UnusedImportedValueOrType {
|
UnusedImportedValueOrType {
|
||||||
#[label]
|
#[label("unused import")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I found an unused private function: '{}'.\n",
|
"I found an unused private function: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple()),
|
name.if_supports_color(Stderr, |s| s.default_color()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"Perhaps your forgot to make it public using the '{keyword_pub}' keyword?\n\
|
"Perhaps your forgot to make it public using the {keyword_pub} keyword?\n\
|
||||||
Otherwise, you might want to get rid of it altogether.",
|
Otherwise, you might want to get rid of it altogether.",
|
||||||
keyword_pub = "pub".if_supports_color(Stderr, |s| s.bright_blue())
|
keyword_pub = "pub".if_supports_color(Stderr, |s| s.bright_blue())
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused::function"))]
|
#[diagnostic(code("unused::function"))]
|
||||||
UnusedPrivateFunction {
|
UnusedPrivateFunction {
|
||||||
#[label]
|
#[label("unused (private) function")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I found an unused (private) module constant: '{}'.\n",
|
"I found an unused (private) module constant: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name.if_supports_color(Stderr, |s| s.default_color()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"Perhaps your forgot to make it public using the '{keyword_pub}' keyword?\n\
|
"Perhaps your forgot to make it public using the {keyword_pub} keyword?\n\
|
||||||
Otherwise, you might want to get rid of it altogether.",
|
Otherwise, you might want to get rid of it altogether.",
|
||||||
keyword_pub = "pub".if_supports_color(Stderr, |s| s.bright_blue())
|
keyword_pub = "pub".if_supports_color(Stderr, |s| s.bright_blue())
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused::constant"))]
|
#[diagnostic(code("unused::constant"))]
|
||||||
UnusedPrivateModuleConstant {
|
UnusedPrivateModuleConstant {
|
||||||
#[label]
|
#[label("unused (private) constant")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I discovered an unused type: '{}'.\n",
|
"I discovered an unused type: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name
|
||||||
|
.if_supports_color(Stderr, |s| s.bright_blue())
|
||||||
|
.if_supports_color(Stderr, |s| s.bold())
|
||||||
)]
|
)]
|
||||||
#[diagnostic(code("unused::type"))]
|
#[diagnostic(code("unused::type"))]
|
||||||
UnusedType {
|
UnusedType {
|
||||||
#[label]
|
#[label("unused (private) type")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I came across an unused variable: {}.\n",
|
"I came across an unused variable: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name.if_supports_color(Stderr, |s| s.default_color()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help("{}", formatdoc! {
|
#[diagnostic(help("{}", formatdoc! {
|
||||||
r#"No big deal, but you might want to remove it or use a discard {name} to get rid of that warning.
|
r#"No big deal, but you might want to remove it or use a discard {name} to get rid of that warning.
|
||||||
|
@ -1663,14 +1666,14 @@ pub enum Warning {
|
||||||
}))]
|
}))]
|
||||||
#[diagnostic(code("unused::variable"))]
|
#[diagnostic(code("unused::variable"))]
|
||||||
UnusedVariable {
|
UnusedVariable {
|
||||||
#[label("unused")]
|
#[label("unused identifier")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I came across a discarded variable in a let assignment: {}.\n",
|
"I came across a discarded variable in a let assignment: {}",
|
||||||
name.if_supports_color(Stderr, |s| s.purple())
|
name.if_supports_color(Stderr, |s| s.default_color())
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help("{}", formatdoc! {
|
#[diagnostic(help("{}", formatdoc! {
|
||||||
r#"If you do want to enforce some side-effects, use {keyword_expect} with {name} instead of {keyword_let}.
|
r#"If you do want to enforce some side-effects, use {keyword_expect} with {name} instead of {keyword_let}.
|
||||||
|
@ -1685,14 +1688,15 @@ pub enum Warning {
|
||||||
}))]
|
}))]
|
||||||
#[diagnostic(code("unused::discarded_let_assignment"))]
|
#[diagnostic(code("unused::discarded_let_assignment"))]
|
||||||
DiscardedLetAssignment {
|
DiscardedLetAssignment {
|
||||||
#[label("discarded")]
|
#[label("discarded result")]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I came across a validator in a {} module which means\nI'm going to ignore it.\n",
|
"I came across a validator in a {} {}",
|
||||||
"lib/".if_supports_color(Stderr, |s| s.purple())
|
"lib/".if_supports_color(Stderr, |s| s.purple()),
|
||||||
|
"module which means\nI'm going to ignore it.\n".if_supports_color(Stderr, |s| s.yellow()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"No big deal, but you might want to move it to a {} module\nor remove it to get rid of that warning.",
|
"No big deal, but you might want to move it to a {} module\nor remove it to get rid of that warning.",
|
||||||
|
@ -1700,15 +1704,16 @@ pub enum Warning {
|
||||||
))]
|
))]
|
||||||
#[diagnostic(code("unused::validator"))]
|
#[diagnostic(code("unused::validator"))]
|
||||||
ValidatorInLibraryModule {
|
ValidatorInLibraryModule {
|
||||||
#[label("unused")]
|
#[label("unused validator")]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I noticed a suspicious {type_ByteArray} UTF-8 literal which resembles a hash digest.",
|
"I noticed a suspicious {type_ByteArray} {tail}",
|
||||||
type_ByteArray = "ByteArray"
|
type_ByteArray = "ByteArray"
|
||||||
.if_supports_color(Stderr, |s| s.bright_blue())
|
.if_supports_color(Stderr, |s| s.bright_blue())
|
||||||
.if_supports_color(Stderr, |s| s.bold())
|
.if_supports_color(Stderr, |s| s.bold()),
|
||||||
|
tail = "UTF-8 literal which resembles a hash digest.".if_supports_color(Stderr, |s| s.yellow()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(help("{}", formatdoc! {
|
#[diagnostic(help("{}", formatdoc! {
|
||||||
r#"When you specify a {type_ByteArray} literal using plain double-quotes, it's interpreted as an array of UTF-8 bytes. For example, the literal {literal_foo} is interpreted as the byte sequence {foo_bytes}.
|
r#"When you specify a {type_ByteArray} literal using plain double-quotes, it's interpreted as an array of UTF-8 bytes. For example, the literal {literal_foo} is interpreted as the byte sequence {foo_bytes}.
|
||||||
|
@ -1793,11 +1798,9 @@ fn format_suggestion(sample: &UntypedExpr) -> String {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(ix, line)| {
|
.map(|(ix, line)| {
|
||||||
if ix == 0 {
|
if ix == 0 {
|
||||||
format!("╰─▶ {}", line.if_supports_color(Stdout, |s| s.yellow()))
|
format!("╰─▶ {line}")
|
||||||
} else {
|
} else {
|
||||||
format!(" {line}")
|
format!(" {line}")
|
||||||
.if_supports_color(Stdout, |s| s.yellow())
|
|
||||||
.to_string()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{blueprint::error as blueprint, deps::manifest::Package, package_name::PackageName};
|
use crate::{blueprint, deps::manifest::Package, package_name::PackageName};
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{self, Span},
|
ast::{self, Span},
|
||||||
error::ExtraData,
|
error::ExtraData,
|
||||||
|
@ -6,7 +6,8 @@ use aiken_lang::{
|
||||||
tipo,
|
tipo,
|
||||||
};
|
};
|
||||||
use miette::{
|
use miette::{
|
||||||
Diagnostic, EyreContext, LabeledSpan, MietteHandlerOpts, NamedSource, RgbColors, SourceCode,
|
Diagnostic, EyreContext, LabeledSpan, MietteHandler, MietteHandlerOpts, NamedSource, RgbColors,
|
||||||
|
SourceCode,
|
||||||
};
|
};
|
||||||
use owo_colors::{
|
use owo_colors::{
|
||||||
OwoColorize,
|
OwoColorize,
|
||||||
|
@ -157,20 +158,11 @@ impl Error {
|
||||||
|
|
||||||
impl Debug for Error {
|
impl Debug for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let miette_handler = MietteHandlerOpts::new()
|
default_miette_handler(2)
|
||||||
// For better support of terminal themes use the ANSI coloring
|
.debug(self, f)
|
||||||
.rgb_colors(RgbColors::Never)
|
|
||||||
// If ansi support is disabled in the config disable the eye-candy
|
|
||||||
.color(true)
|
|
||||||
.unicode(true)
|
|
||||||
.terminal_links(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Ignore error to prevent format! panics. This can happen if span points at some
|
// Ignore error to prevent format! panics. This can happen if span points at some
|
||||||
// inaccessible location, for example by calling `report_error()` with wrong working set.
|
// inaccessible location, for example by calling `report_error()` with wrong working set.
|
||||||
let _ = miette_handler.debug(self, f);
|
.or(Ok(()))
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,9 +496,9 @@ impl Diagnostic for Error {
|
||||||
|
|
||||||
#[derive(thiserror::Error)]
|
#[derive(thiserror::Error)]
|
||||||
pub enum Warning {
|
pub enum Warning {
|
||||||
#[error("{}", "You do not have any validators to build!".if_supports_color(Stderr, |s| s.yellow()))]
|
#[error("You do not have any validators to build!")]
|
||||||
NoValidators,
|
NoValidators,
|
||||||
#[error("{}", "While trying to make sense of your code...".if_supports_color(Stderr, |s| s.yellow()))]
|
#[error("{}", warning)]
|
||||||
Type {
|
Type {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
src: String,
|
src: String,
|
||||||
|
@ -514,9 +506,9 @@ pub enum Warning {
|
||||||
#[source]
|
#[source]
|
||||||
warning: tipo::error::Warning,
|
warning: tipo::error::Warning,
|
||||||
},
|
},
|
||||||
#[error("{}", format!("{name} is already a dependency.").if_supports_color(Stderr, |s| s.yellow()))]
|
#[error("{name} is already a dependency.")]
|
||||||
DependencyAlreadyExists { name: PackageName },
|
DependencyAlreadyExists { name: PackageName },
|
||||||
#[error("{}", format!("Ignoring file with invalid module name at: {path:?}").if_supports_color(Stderr, |s| s.yellow()))]
|
#[error("Ignoring file with invalid module name at: {path:?}")]
|
||||||
InvalidModuleName { path: PathBuf },
|
InvalidModuleName { path: PathBuf },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +565,17 @@ impl Diagnostic for Warning {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
None
|
match self {
|
||||||
|
Warning::Type { warning, .. } => Some(Box::new(format!(
|
||||||
|
"aiken::check{}",
|
||||||
|
warning.code().map(|s| format!("::{s}")).unwrap_or_default()
|
||||||
|
))),
|
||||||
|
Warning::NoValidators => Some(Box::new("aiken::check")),
|
||||||
|
Warning::InvalidModuleName { .. } => Some(Box::new("aiken::project::module_name")),
|
||||||
|
Warning::DependencyAlreadyExists { .. } => {
|
||||||
|
Some(Box::new("aiken::packages::already_exists"))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
|
@ -607,20 +609,63 @@ impl Warning {
|
||||||
|
|
||||||
impl Debug for Warning {
|
impl Debug for Warning {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let miette_handler = MietteHandlerOpts::new()
|
default_miette_handler(0)
|
||||||
// For better support of terminal themes use the ANSI coloring
|
.debug(
|
||||||
.rgb_colors(RgbColors::Never)
|
&DisplayWarning {
|
||||||
// If ansi support is disabled in the config disable the eye-candy
|
title: &self.to_string(),
|
||||||
.color(true)
|
source_code: self.source_code(),
|
||||||
.unicode(true)
|
labels: self.labels().map(|ls| ls.collect()),
|
||||||
.terminal_links(true)
|
help: self.help().map(|s| s.to_string()),
|
||||||
.build();
|
},
|
||||||
|
f,
|
||||||
|
)
|
||||||
// Ignore error to prevent format! panics. This can happen if span points at some
|
// Ignore error to prevent format! panics. This can happen if span points at some
|
||||||
// inaccessible location, for example by calling `report_error()` with wrong working set.
|
// inaccessible location, for example by calling `report_error()` with wrong working set.
|
||||||
let _ = miette_handler.debug(self, f);
|
.or(Ok(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
#[derive(thiserror::Error)]
|
||||||
|
#[error("{}", title.if_supports_color(Stderr, |s| s.yellow()))]
|
||||||
|
struct DisplayWarning<'a> {
|
||||||
|
title: &'a str,
|
||||||
|
source_code: Option<&'a dyn miette::SourceCode>,
|
||||||
|
labels: Option<Vec<LabeledSpan>>,
|
||||||
|
help: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Diagnostic for DisplayWarning<'a> {
|
||||||
|
fn severity(&self) -> Option<miette::Severity> {
|
||||||
|
Some(miette::Severity::Warning)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn source_code(&self) -> Option<&dyn SourceCode> {
|
||||||
|
self.source_code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
|
||||||
|
self.labels
|
||||||
|
.as_ref()
|
||||||
|
.map(|ls| ls.iter().cloned())
|
||||||
|
.map(Box::new)
|
||||||
|
.map(|b| b as Box<dyn Iterator<Item = LabeledSpan>>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn code<'b>(&'b self) -> Option<Box<dyn Display + 'b>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn help<'b>(&'b self) -> Option<Box<dyn Display + 'b>> {
|
||||||
|
self.help
|
||||||
|
.as_ref()
|
||||||
|
.map(Box::new)
|
||||||
|
.map(|b| b as Box<dyn Display + 'b>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Debug for DisplayWarning<'a> {
|
||||||
|
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
unreachable!("Display warning are never shown directly.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,3 +676,14 @@ pub struct Unformatted {
|
||||||
pub input: String,
|
pub input: String,
|
||||||
pub output: String,
|
pub output: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_miette_handler(context_lines: usize) -> MietteHandler {
|
||||||
|
MietteHandlerOpts::new()
|
||||||
|
// For better support of terminal themes use the ANSI coloring
|
||||||
|
.rgb_colors(RgbColors::Never)
|
||||||
|
// If ansi support is disabled in the config disable the eye-candy
|
||||||
|
.unicode(true)
|
||||||
|
.terminal_links(true)
|
||||||
|
.context_lines(context_lines)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue