diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs')
-rw-r--r-- | third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs b/third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs new file mode 100644 index 0000000000..d05dee8549 --- /dev/null +++ b/third_party/rust/codespan-reporting/examples/reusable_diagnostic.rs @@ -0,0 +1,105 @@ +use codespan_reporting::diagnostic::{Diagnostic, Label}; +use codespan_reporting::files::SimpleFile; +use codespan_reporting::term::termcolor::StandardStream; +use codespan_reporting::term::{self, ColorArg}; +use std::ops::Range; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +#[structopt(name = "emit")] +pub struct Opts { + #[structopt(long = "color", + parse(try_from_str), + default_value = "auto", + possible_values = ColorArg::VARIANTS, + case_insensitive = true + )] + color: ColorArg, +} + +fn main() -> anyhow::Result<()> { + let file = SimpleFile::new( + "main.rs", + unindent::unindent( + r#" + fn main() { + let foo: i32 = "hello, world"; + foo += 1; + } + "#, + ), + ); + + let errors = [ + Error::MismatchType( + Item::new(20..23, "i32"), + Item::new(31..45, "\"hello, world\""), + ), + Error::MutatingImmutable(Item::new(20..23, "foo"), Item::new(51..59, "foo += 1")), + ]; + + let opts = Opts::from_args(); + let writer = StandardStream::stderr(opts.color.into()); + let config = codespan_reporting::term::Config::default(); + for diagnostic in errors.iter().map(Error::report) { + term::emit(&mut writer.lock(), &config, &file, &diagnostic)?; + } + + Ok(()) +} + +/// An error enum that represent all possible errors within your program +enum Error { + MismatchType(Item, Item), + MutatingImmutable(Item, Item), +} + +impl Error { + fn report(&self) -> Diagnostic<()> { + match self { + Error::MismatchType(left, right) => Diagnostic::error() + .with_code("E0308") + .with_message("mismatch types") + .with_labels(vec![ + Label::primary((), right.range.clone()).with_message(format!( + "Expected `{}`, found: `{}`", + left.content, right.content, + )), + Label::secondary((), left.range.clone()).with_message("expected due to this"), + ]), + Error::MutatingImmutable(original, mutating) => Diagnostic::error() + .with_code("E0384") + .with_message(format!( + "cannot mutate immutable variable `{}`", + original.content, + )) + .with_labels(vec![ + Label::secondary((), original.range.clone()).with_message(unindent::unindent( + &format!( + r#" + first assignment to `{0}` + help: make this binding mutable: `mut {0}` + "#, + original.content, + ), + )), + Label::primary((), mutating.range.clone()) + .with_message("cannot assign twice to immutable variable"), + ]), + } + } +} + +/// An item in the source code to be used in the `Error` enum. +/// In a more complex program it could also contain a `files::FileId` to handle errors that occur inside multiple files. +struct Item { + range: Range<usize>, + content: String, +} + +impl Item { + fn new(range: Range<usize>, content: impl Into<String>) -> Item { + let content = content.into(); + Item { range, content } + } +} |