aboutsummaryrefslogtreecommitdiff
path: root/vendor/miette/src/protocol.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/miette/src/protocol.rs')
-rw-r--r--vendor/miette/src/protocol.rs697
1 files changed, 0 insertions, 697 deletions
diff --git a/vendor/miette/src/protocol.rs b/vendor/miette/src/protocol.rs
deleted file mode 100644
index f516984..0000000
--- a/vendor/miette/src/protocol.rs
+++ /dev/null
@@ -1,697 +0,0 @@
-/*!
-This module defines the core of the miette protocol: a series of types and
-traits that you can implement to get access to miette's (and related library's)
-full reporting and such features.
-*/
-use std::{
- fmt::{self, Display},
- fs,
- panic::Location,
-};
-
-#[cfg(feature = "serde")]
-use serde::{Deserialize, Serialize};
-
-use crate::MietteError;
-
-/// Adds rich metadata to your Error that can be used by
-/// [`Report`](crate::Report) to print really nice and human-friendly error
-/// messages.
-pub trait Diagnostic: std::error::Error {
- /// 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<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
- None
- }
-
- /// Diagnostic severity. This may be used by
- /// [`ReportHandler`](crate::ReportHandler)s to change the display format
- /// of this diagnostic.
- ///
- /// If `None`, reporters should treat this as [`Severity::Error`].
- fn severity(&self) -> Option<Severity> {
- None
- }
-
- /// 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<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
- None
- }
-
- /// URL to visit for a more detailed explanation/help about this
- /// `Diagnostic`.
- fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
- None
- }
-
- /// Source code to apply this `Diagnostic`'s [`Diagnostic::labels`] to.
- fn source_code(&self) -> Option<&dyn SourceCode> {
- None
- }
-
- /// Labels to apply to this `Diagnostic`'s [`Diagnostic::source_code`]
- fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
- None
- }
-
- /// Additional related `Diagnostic`s.
- fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
- None
- }
-
- /// The cause of the error.
- fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
- None
- }
-}
-
-macro_rules! box_impls {
- ($($box_type:ty),*) => {
- $(
- impl std::error::Error for $box_type {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- (**self).source()
- }
-
- fn cause(&self) -> Option<&dyn std::error::Error> {
- self.source()
- }
- }
- )*
- }
-}
-
-box_impls! {
- Box<dyn Diagnostic>,
- Box<dyn Diagnostic + Send>,
- Box<dyn Diagnostic + Send + Sync>
-}
-
-impl<T: Diagnostic + Send + Sync + 'static> From<T>
- for Box<dyn Diagnostic + Send + Sync + 'static>
-{
- fn from(diag: T) -> Self {
- Box::new(diag)
- }
-}
-
-impl<T: Diagnostic + Send + Sync + 'static> From<T> for Box<dyn Diagnostic + Send + 'static> {
- fn from(diag: T) -> Self {
- Box::<dyn Diagnostic + Send + Sync>::from(diag)
- }
-}
-
-impl<T: Diagnostic + Send + Sync + 'static> From<T> for Box<dyn Diagnostic + 'static> {
- fn from(diag: T) -> Self {
- Box::<dyn Diagnostic + Send + Sync>::from(diag)
- }
-}
-
-impl From<&str> for Box<dyn Diagnostic> {
- fn from(s: &str) -> Self {
- From::from(String::from(s))
- }
-}
-
-impl<'a> From<&str> for Box<dyn Diagnostic + Send + Sync + 'a> {
- fn from(s: &str) -> Self {
- From::from(String::from(s))
- }
-}
-
-impl From<String> for Box<dyn Diagnostic> {
- fn from(s: String) -> Self {
- let err1: Box<dyn Diagnostic + Send + Sync> = From::from(s);
- let err2: Box<dyn Diagnostic> = err1;
- err2
- }
-}
-
-impl From<String> for Box<dyn Diagnostic + Send + Sync> {
- fn from(s: String) -> Self {
- struct StringError(String);
-
- impl std::error::Error for StringError {}
- impl Diagnostic for StringError {}
-
- impl Display for StringError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- Display::fmt(&self.0, f)
- }
- }
-
- // Purposefully skip printing "StringError(..)"
- impl fmt::Debug for StringError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&self.0, f)
- }
- }
-
- Box::new(StringError(s))
- }
-}
-
-impl From<Box<dyn std::error::Error + Send + Sync>> for Box<dyn Diagnostic + Send + Sync> {
- fn from(s: Box<dyn std::error::Error + Send + Sync>) -> Self {
- #[derive(thiserror::Error)]
- #[error(transparent)]
- struct BoxedDiagnostic(Box<dyn std::error::Error + Send + Sync>);
- impl fmt::Debug for BoxedDiagnostic {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&self.0, f)
- }
- }
-
- impl Diagnostic for BoxedDiagnostic {}
-
- Box::new(BoxedDiagnostic(s))
- }
-}
-
-/**
-[`Diagnostic`] severity. Intended to be used by
-[`ReportHandler`](crate::ReportHandler)s to change the way different
-[`Diagnostic`]s are displayed. Defaults to [`Severity::Error`].
-*/
-#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-pub enum Severity {
- /// Just some help. Here's how you could be doing it better.
- Advice,
- /// Warning. Please take note.
- Warning,
- /// Critical failure. The program cannot continue.
- /// This is the default severity, if you don't specify another one.
- Error,
-}
-
-impl Default for Severity {
- fn default() -> Self {
- Severity::Error
- }
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_serialize_severity() {
- use serde_json::json;
-
- assert_eq!(json!(Severity::Advice), json!("Advice"));
- assert_eq!(json!(Severity::Warning), json!("Warning"));
- assert_eq!(json!(Severity::Error), json!("Error"));
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_deserialize_severity() {
- use serde_json::json;
-
- let severity: Severity = serde_json::from_value(json!("Advice")).unwrap();
- assert_eq!(severity, Severity::Advice);
-
- let severity: Severity = serde_json::from_value(json!("Warning")).unwrap();
- assert_eq!(severity, Severity::Warning);
-
- let severity: Severity = serde_json::from_value(json!("Error")).unwrap();
- assert_eq!(severity, Severity::Error);
-}
-
-/**
-Represents readable source code of some sort.
-
-This trait is able to support simple `SourceCode` types like [`String`]s, as
-well as more involved types like indexes into centralized `SourceMap`-like
-types, file handles, and even network streams.
-
-If you can read it, you can source it, and it's not necessary to read the
-whole thing--meaning you should be able to support `SourceCode`s which are
-gigabytes or larger in size.
-*/
-pub trait SourceCode: Send + Sync {
- /// Read the bytes for a specific span from this SourceCode, keeping a
- /// certain number of lines before and after the span as context.
- fn read_span<'a>(
- &'a self,
- span: &SourceSpan,
- context_lines_before: usize,
- context_lines_after: usize,
- ) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>;
-}
-
-/// A labeled [`SourceSpan`].
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-pub struct LabeledSpan {
- #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
- label: Option<String>,
- span: SourceSpan,
-}
-
-impl LabeledSpan {
- /// Makes a new labeled span.
- pub const fn new(label: Option<String>, offset: ByteOffset, len: usize) -> Self {
- Self {
- label,
- span: SourceSpan::new(SourceOffset(offset), SourceOffset(len)),
- }
- }
-
- /// Makes a new labeled span using an existing span.
- pub fn new_with_span(label: Option<String>, span: impl Into<SourceSpan>) -> Self {
- Self {
- label,
- span: span.into(),
- }
- }
-
- /// Makes a new label at specified span
- ///
- /// # Examples
- /// ```
- /// use miette::LabeledSpan;
- ///
- /// let source = "Cpp is the best";
- /// let label = LabeledSpan::at(0..3, "should be Rust");
- /// assert_eq!(
- /// label,
- /// LabeledSpan::new(Some("should be Rust".to_string()), 0, 3)
- /// )
- /// ```
- pub fn at(span: impl Into<SourceSpan>, label: impl Into<String>) -> Self {
- Self::new_with_span(Some(label.into()), span)
- }
-
- /// Makes a new label that points at a specific offset.
- ///
- /// # Examples
- /// ```
- /// use miette::LabeledSpan;
- ///
- /// let source = "(2 + 2";
- /// let label = LabeledSpan::at_offset(4, "expected a closing parenthesis");
- /// assert_eq!(
- /// label,
- /// LabeledSpan::new(Some("expected a closing parenthesis".to_string()), 4, 0)
- /// )
- /// ```
- pub fn at_offset(offset: ByteOffset, label: impl Into<String>) -> Self {
- Self::new(Some(label.into()), offset, 0)
- }
-
- /// Makes a new label without text, that underlines a specific span.
- ///
- /// # Examples
- /// ```
- /// use miette::LabeledSpan;
- ///
- /// let source = "You have an eror here";
- /// let label = LabeledSpan::underline(12..16);
- /// assert_eq!(label, LabeledSpan::new(None, 12, 4))
- /// ```
- pub fn underline(span: impl Into<SourceSpan>) -> Self {
- Self::new_with_span(None, span)
- }
-
- /// Gets the (optional) label string for this `LabeledSpan`.
- pub fn label(&self) -> Option<&str> {
- self.label.as_deref()
- }
-
- /// Returns a reference to the inner [`SourceSpan`].
- pub const fn inner(&self) -> &SourceSpan {
- &self.span
- }
-
- /// Returns the 0-based starting byte offset.
- pub const fn offset(&self) -> usize {
- self.span.offset()
- }
-
- /// Returns the number of bytes this `LabeledSpan` spans.
- pub const fn len(&self) -> usize {
- self.span.len()
- }
-
- /// True if this `LabeledSpan` is empty.
- pub const fn is_empty(&self) -> bool {
- self.span.is_empty()
- }
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_serialize_labeled_span() {
- use serde_json::json;
-
- assert_eq!(
- json!(LabeledSpan::new(None, 0, 0)),
- json!({
- "span": { "offset": 0, "length": 0 }
- })
- );
-
- assert_eq!(
- json!(LabeledSpan::new(Some("label".to_string()), 0, 0)),
- json!({
- "label": "label",
- "span": { "offset": 0, "length": 0 }
- })
- )
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_deserialize_labeled_span() {
- use serde_json::json;
-
- let span: LabeledSpan = serde_json::from_value(json!({
- "label": null,
- "span": { "offset": 0, "length": 0 }
- }))
- .unwrap();
- assert_eq!(span, LabeledSpan::new(None, 0, 0));
-
- let span: LabeledSpan = serde_json::from_value(json!({
- "span": { "offset": 0, "length": 0 }
- }))
- .unwrap();
- assert_eq!(span, LabeledSpan::new(None, 0, 0));
-
- let span: LabeledSpan = serde_json::from_value(json!({
- "label": "label",
- "span": { "offset": 0, "length": 0 }
- }))
- .unwrap();
- assert_eq!(span, LabeledSpan::new(Some("label".to_string()), 0, 0))
-}
-
-/**
-Contents of a [`SourceCode`] covered by [`SourceSpan`].
-
-Includes line and column information to optimize highlight calculations.
-*/
-pub trait SpanContents<'a> {
- /// Reference to the data inside the associated span, in bytes.
- fn data(&self) -> &'a [u8];
- /// [`SourceSpan`] representing the span covered by this `SpanContents`.
- fn span(&self) -> &SourceSpan;
- /// An optional (file?) name for the container of this `SpanContents`.
- fn name(&self) -> Option<&str> {
- None
- }
- /// The 0-indexed line in the associated [`SourceCode`] where the data
- /// begins.
- fn line(&self) -> usize;
- /// The 0-indexed column in the associated [`SourceCode`] where the data
- /// begins, relative to `line`.
- fn column(&self) -> usize;
- /// Total number of lines covered by this `SpanContents`.
- fn line_count(&self) -> usize;
-}
-
-/**
-Basic implementation of the [`SpanContents`] trait, for convenience.
-*/
-#[derive(Clone, Debug)]
-pub struct MietteSpanContents<'a> {
- // Data from a [`SourceCode`], in bytes.
- data: &'a [u8],
- // span actually covered by this SpanContents.
- span: SourceSpan,
- // The 0-indexed line where the associated [`SourceSpan`] _starts_.
- line: usize,
- // The 0-indexed column where the associated [`SourceSpan`] _starts_.
- column: usize,
- // Number of line in this snippet.
- line_count: usize,
- // Optional filename
- name: Option<String>,
-}
-
-impl<'a> MietteSpanContents<'a> {
- /// Make a new [`MietteSpanContents`] object.
- pub const fn new(
- data: &'a [u8],
- span: SourceSpan,
- line: usize,
- column: usize,
- line_count: usize,
- ) -> MietteSpanContents<'a> {
- MietteSpanContents {
- data,
- span,
- line,
- column,
- line_count,
- name: None,
- }
- }
-
- /// Make a new [`MietteSpanContents`] object, with a name for its 'file'.
- pub const fn new_named(
- name: String,
- data: &'a [u8],
- span: SourceSpan,
- line: usize,
- column: usize,
- line_count: usize,
- ) -> MietteSpanContents<'a> {
- MietteSpanContents {
- data,
- span,
- line,
- column,
- line_count,
- name: Some(name),
- }
- }
-}
-
-impl<'a> SpanContents<'a> for MietteSpanContents<'a> {
- fn data(&self) -> &'a [u8] {
- self.data
- }
- fn span(&self) -> &SourceSpan {
- &self.span
- }
- fn line(&self) -> usize {
- self.line
- }
- fn column(&self) -> usize {
- self.column
- }
- fn line_count(&self) -> usize {
- self.line_count
- }
- fn name(&self) -> Option<&str> {
- self.name.as_deref()
- }
-}
-
-/// Span within a [`SourceCode`]
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-pub struct SourceSpan {
- /// The start of the span.
- offset: SourceOffset,
- /// The total length of the span
- length: usize,
-}
-
-impl SourceSpan {
- /// Create a new [`SourceSpan`].
- pub const fn new(start: SourceOffset, length: SourceOffset) -> Self {
- Self {
- offset: start,
- length: length.offset(),
- }
- }
-
- /// The absolute offset, in bytes, from the beginning of a [`SourceCode`].
- pub const fn offset(&self) -> usize {
- self.offset.offset()
- }
-
- /// Total length of the [`SourceSpan`], in bytes.
- pub const fn len(&self) -> usize {
- self.length
- }
-
- /// Whether this [`SourceSpan`] has a length of zero. It may still be useful
- /// to point to a specific point.
- pub const fn is_empty(&self) -> bool {
- self.length == 0
- }
-}
-
-impl From<(ByteOffset, usize)> for SourceSpan {
- fn from((start, len): (ByteOffset, usize)) -> Self {
- Self {
- offset: start.into(),
- length: len,
- }
- }
-}
-
-impl From<(SourceOffset, SourceOffset)> for SourceSpan {
- fn from((start, len): (SourceOffset, SourceOffset)) -> Self {
- Self::new(start, len)
- }
-}
-
-impl From<std::ops::Range<ByteOffset>> for SourceSpan {
- fn from(range: std::ops::Range<ByteOffset>) -> Self {
- Self {
- offset: range.start.into(),
- length: range.len(),
- }
- }
-}
-
-impl From<SourceOffset> for SourceSpan {
- fn from(offset: SourceOffset) -> Self {
- Self { offset, length: 0 }
- }
-}
-
-impl From<ByteOffset> for SourceSpan {
- fn from(offset: ByteOffset) -> Self {
- Self {
- offset: offset.into(),
- length: 0,
- }
- }
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_serialize_source_span() {
- use serde_json::json;
-
- assert_eq!(
- json!(SourceSpan::from(0)),
- json!({ "offset": 0, "length": 0})
- )
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_deserialize_source_span() {
- use serde_json::json;
-
- let span: SourceSpan = serde_json::from_value(json!({ "offset": 0, "length": 0})).unwrap();
- assert_eq!(span, SourceSpan::from(0))
-}
-
-/**
-"Raw" type for the byte offset from the beginning of a [`SourceCode`].
-*/
-pub type ByteOffset = usize;
-
-/**
-Newtype that represents the [`ByteOffset`] from the beginning of a [`SourceCode`]
-*/
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-pub struct SourceOffset(ByteOffset);
-
-impl SourceOffset {
- /// Actual byte offset.
- pub const fn offset(&self) -> ByteOffset {
- self.0
- }
-
- /// Little utility to help convert 1-based line/column locations into
- /// miette-compatible Spans
- ///
- /// This function is infallible: Giving an out-of-range line/column pair
- /// will return the offset of the last byte in the source.
- pub fn from_location(source: impl AsRef<str>, loc_line: usize, loc_col: usize) -> Self {
- let mut line = 0usize;
- let mut col = 0usize;
- let mut offset = 0usize;
- for char in source.as_ref().chars() {
- if line + 1 >= loc_line && col + 1 >= loc_col {
- break;
- }
- if char == '\n' {
- col = 0;
- line += 1;
- } else {
- col += 1;
- }
- offset += char.len_utf8();
- }
-
- SourceOffset(offset)
- }
-
- /// Returns an offset for the _file_ location of wherever this function is
- /// called. If you want to get _that_ caller's location, mark this
- /// function's caller with `#[track_caller]` (and so on and so forth).
- ///
- /// Returns both the filename that was given and the offset of the caller
- /// as a [`SourceOffset`].
- ///
- /// Keep in mind that this fill only work if the file your Rust source
- /// file was compiled from is actually available at that location. If
- /// you're shipping binaries for your application, you'll want to ignore
- /// the Err case or otherwise report it.
- #[track_caller]
- pub fn from_current_location() -> Result<(String, Self), MietteError> {
- let loc = Location::caller();
- Ok((
- loc.file().into(),
- fs::read_to_string(loc.file())
- .map(|txt| Self::from_location(txt, loc.line() as usize, loc.column() as usize))?,
- ))
- }
-}
-
-impl From<ByteOffset> for SourceOffset {
- fn from(bytes: ByteOffset) -> Self {
- SourceOffset(bytes)
- }
-}
-
-#[test]
-fn test_source_offset_from_location() {
- let source = "f\n\noo\r\nbar";
-
- assert_eq!(SourceOffset::from_location(source, 1, 1).offset(), 0);
- assert_eq!(SourceOffset::from_location(source, 1, 2).offset(), 1);
- assert_eq!(SourceOffset::from_location(source, 2, 1).offset(), 2);
- assert_eq!(SourceOffset::from_location(source, 3, 1).offset(), 3);
- assert_eq!(SourceOffset::from_location(source, 3, 2).offset(), 4);
- assert_eq!(SourceOffset::from_location(source, 3, 3).offset(), 5);
- assert_eq!(SourceOffset::from_location(source, 3, 4).offset(), 6);
- assert_eq!(SourceOffset::from_location(source, 4, 1).offset(), 7);
- assert_eq!(SourceOffset::from_location(source, 4, 2).offset(), 8);
- assert_eq!(SourceOffset::from_location(source, 4, 3).offset(), 9);
- assert_eq!(SourceOffset::from_location(source, 4, 4).offset(), 10);
-
- // Out-of-range
- assert_eq!(
- SourceOffset::from_location(source, 5, 1).offset(),
- source.len()
- );
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_serialize_source_offset() {
- use serde_json::json;
-
- assert_eq!(json!(SourceOffset::from(0)), 0)
-}
-
-#[cfg(feature = "serde")]
-#[test]
-fn test_deserialize_source_offset() {
- let offset: SourceOffset = serde_json::from_str("0").unwrap();
- assert_eq!(offset, SourceOffset::from(0))
-}