-
-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(protocol): sketched out a basic protocol
- Loading branch information
Showing
3 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#![doc = include_str!("../README.md")] | ||
|
||
pub use protocol::*; | ||
|
||
mod source_impls; | ||
mod protocol; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
use std::fmt::Display; | ||
use std::io::{self, Read}; | ||
|
||
/** | ||
Adds rich metadata to your Error that can be used by [DiagnosticReporter] to print | ||
really nice and human-friendly error messages. | ||
*/ | ||
pub trait Diagnostic: std::error::Error + Send + Sync + 'static { | ||
/// Unique diagnostic code that can be used to look up more information | ||
/// about this Diagnostic. Ideally also globally unique, and documented in | ||
/// the toplevel crate's documentation for easy searching. Rust path | ||
/// format (`foo::bar::baz`) is recommended, but more classic codes like | ||
/// `E0123` or Enums will work just fine. | ||
fn code(&self) -> Box<dyn Display>; | ||
|
||
/// Diagnostic severity. This may be used by [Reporter]s to change the | ||
/// display format of this diagnostic. | ||
fn severity(&self) -> Severity; | ||
|
||
/// Additional help text related to this Diagnostic. Do you have any | ||
/// advice for the poor soul who's just run into this issue? | ||
fn help(&self) -> Option<Vec<Box<dyn Display>>> { | ||
None | ||
} | ||
|
||
/// Additional contextual details. This is typically used for adding | ||
/// marked-up source file output the way compilers often do. | ||
fn details(&self) -> Option<&[DiagnosticDetail]> { | ||
None | ||
} | ||
} | ||
|
||
/** | ||
Protocol for [Diagnostic] handlers, which are responsible for actually printing out Diagnostics. | ||
Blatantly based on [EyreHandler](https://docs.rs/eyre/0.6.5/eyre/trait.EyreHandler.html) (thanks, Jane!) | ||
*/ | ||
pub trait DiagnosticReporter: core::any::Any + Send + Sync { | ||
/// Define the report format. | ||
fn debug( | ||
&self, | ||
diagnostic: &(dyn Diagnostic), | ||
f: &mut core::fmt::Formatter<'_>, | ||
) -> core::fmt::Result; | ||
|
||
/// Override for the `Display` format. | ||
fn display( | ||
&self, | ||
diagnostic: &(dyn Diagnostic), | ||
f: &mut core::fmt::Formatter<'_>, | ||
) -> core::fmt::Result { | ||
write!(f, "{}", diagnostic)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
/** | ||
[Diagnostic] severity. Intended to be used by [DiagnosticReporter] to change the | ||
way different Diagnostics are displayed. | ||
*/ | ||
#[derive(Copy, Clone, Debug)] | ||
pub enum Severity { | ||
/// Critical failure. The program cannot continue. | ||
Error, | ||
/// Warning. Please take note. | ||
Warning, | ||
/// Just some help. Here's how you could be doing it better. | ||
Advice, | ||
} | ||
|
||
/** | ||
Represents a readable source of some sort: a source file, a String, etc. | ||
*/ | ||
pub trait Source { | ||
/// Get a `Read`er from a given [Source]. | ||
fn open(&self) -> io::Result<Box<dyn Read>>; | ||
} | ||
|
||
/** | ||
Details and additional context to be displayed. | ||
*/ | ||
pub struct DiagnosticDetail { | ||
/// Explanation of this specific diagnostic detail. | ||
pub message: Option<String>, | ||
/// The "filename" for this diagnostic. | ||
pub source_name: String, | ||
/// A [Source] that can be used to read the actual text of a source. | ||
pub source: Box<dyn Source>, | ||
/// The primary [SourceSpan] where this diagnostic is located. | ||
pub span: SourceSpan, | ||
/// Additional [SourceSpan]s that can add secondary context. | ||
pub other_spans: Option<Vec<SourceSpan>>, | ||
} | ||
|
||
/** | ||
Span within a [Source] with an associated message. | ||
*/ | ||
pub struct SourceSpan { | ||
/// A name for the thing this SourceSpan is actually pointing to. | ||
pub label: String, | ||
/// The start of the span. | ||
pub start: SourceLocation, | ||
/// The end of the span. | ||
pub end: SourceLocation, | ||
} | ||
|
||
/** | ||
Specific location in a [SourceSpan] | ||
*/ | ||
pub struct SourceLocation { | ||
/// 0-indexed column of location. | ||
pub column: usize, | ||
/// 0-indexed line of location. | ||
pub line: usize, | ||
/// 0-indexed _character_ offset of location. | ||
pub offset: usize, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/*! | ||
Default trait implementations for [Source]. | ||
*/ | ||
use std::fs::File; | ||
use std::io::{Cursor, Read, Result}; | ||
use std::path::{Path, PathBuf}; | ||
|
||
use crate::{Source}; | ||
|
||
impl Source for String { | ||
fn open(&self) -> Result<Box<dyn Read>> { | ||
Ok(Box::new(Cursor::new(self.clone()))) | ||
} | ||
} | ||
|
||
impl Source for Path { | ||
fn open(&self) -> Result<Box<dyn Read>> { | ||
Ok(Box::new(File::open(self)?)) | ||
} | ||
} | ||
|
||
impl Source for PathBuf { | ||
fn open(&self) -> Result<Box<dyn Read>> { | ||
Ok(Box::new(File::open(self)?)) | ||
} | ||
} |