summaryrefslogtreecommitdiffstats
path: root/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/annotate-snippets-0.8.0/src/formatter/mod.rs')
-rw-r--r--vendor/annotate-snippets-0.8.0/src/formatter/mod.rs397
1 files changed, 397 insertions, 0 deletions
diff --git a/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs b/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs
new file mode 100644
index 000000000..e93aeb329
--- /dev/null
+++ b/vendor/annotate-snippets-0.8.0/src/formatter/mod.rs
@@ -0,0 +1,397 @@
+use std::{
+ cmp,
+ fmt::{self, Display, Write},
+};
+
+pub mod style;
+
+use self::style::{Style, StyleClass, Stylesheet};
+
+#[cfg(feature = "color")]
+use crate::stylesheets::color::AnsiTermStylesheet;
+use crate::{display_list::*, stylesheets::no_color::NoColorStylesheet};
+
+fn format_repeat_char(c: char, n: usize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ for _ in 0..n {
+ f.write_char(c)?;
+ }
+ Ok(())
+}
+
+#[inline]
+fn is_annotation_empty(annotation: &Annotation<'_>) -> bool {
+ annotation
+ .label
+ .iter()
+ .all(|fragment| fragment.content.is_empty())
+}
+
+#[cfg(feature = "color")]
+#[inline]
+pub fn get_term_style(color: bool) -> Box<dyn Stylesheet> {
+ if color {
+ Box::new(AnsiTermStylesheet)
+ } else {
+ Box::new(NoColorStylesheet)
+ }
+}
+
+#[cfg(not(feature = "color"))]
+#[inline]
+pub fn get_term_style(_color: bool) -> Box<dyn Stylesheet> {
+ Box::new(NoColorStylesheet)
+}
+
+impl<'a> fmt::Display for DisplayList<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let lineno_width = self.body.iter().fold(0, |max, line| match line {
+ DisplayLine::Source {
+ lineno: Some(lineno),
+ ..
+ } => {
+ // The largest line is the largest width.
+ cmp::max(*lineno, max)
+ }
+ _ => max,
+ });
+ let lineno_width = if lineno_width == 0 {
+ lineno_width
+ } else if self.anonymized_line_numbers {
+ Self::ANONYMIZED_LINE_NUM.len()
+ } else {
+ ((lineno_width as f64).log10().floor() as usize) + 1
+ };
+ let inline_marks_width = self.body.iter().fold(0, |max, line| match line {
+ DisplayLine::Source { inline_marks, .. } => cmp::max(inline_marks.len(), max),
+ _ => max,
+ });
+
+ for (i, line) in self.body.iter().enumerate() {
+ self.format_line(line, lineno_width, inline_marks_width, f)?;
+ if i + 1 < self.body.len() {
+ f.write_char('\n')?;
+ }
+ }
+ Ok(())
+ }
+}
+
+impl<'a> DisplayList<'a> {
+ const ANONYMIZED_LINE_NUM: &'static str = "LL";
+ const ERROR_TXT: &'static str = "error";
+ const HELP_TXT: &'static str = "help";
+ const INFO_TXT: &'static str = "info";
+ const NOTE_TXT: &'static str = "note";
+ const WARNING_TXT: &'static str = "warning";
+
+ #[inline]
+ fn format_annotation_type(
+ annotation_type: &DisplayAnnotationType,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ match annotation_type {
+ DisplayAnnotationType::Error => f.write_str(Self::ERROR_TXT),
+ DisplayAnnotationType::Help => f.write_str(Self::HELP_TXT),
+ DisplayAnnotationType::Info => f.write_str(Self::INFO_TXT),
+ DisplayAnnotationType::Note => f.write_str(Self::NOTE_TXT),
+ DisplayAnnotationType::Warning => f.write_str(Self::WARNING_TXT),
+ DisplayAnnotationType::None => Ok(()),
+ }
+ }
+
+ fn annotation_type_len(annotation_type: &DisplayAnnotationType) -> usize {
+ match annotation_type {
+ DisplayAnnotationType::Error => Self::ERROR_TXT.len(),
+ DisplayAnnotationType::Help => Self::HELP_TXT.len(),
+ DisplayAnnotationType::Info => Self::INFO_TXT.len(),
+ DisplayAnnotationType::Note => Self::NOTE_TXT.len(),
+ DisplayAnnotationType::Warning => Self::WARNING_TXT.len(),
+ DisplayAnnotationType::None => 0,
+ }
+ }
+
+ fn get_annotation_style(&self, annotation_type: &DisplayAnnotationType) -> Box<dyn Style> {
+ self.stylesheet.get_style(match annotation_type {
+ DisplayAnnotationType::Error => StyleClass::Error,
+ DisplayAnnotationType::Warning => StyleClass::Warning,
+ DisplayAnnotationType::Info => StyleClass::Info,
+ DisplayAnnotationType::Note => StyleClass::Note,
+ DisplayAnnotationType::Help => StyleClass::Help,
+ DisplayAnnotationType::None => StyleClass::None,
+ })
+ }
+
+ fn format_label(
+ &self,
+ label: &[DisplayTextFragment<'_>],
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ let emphasis_style = self.stylesheet.get_style(StyleClass::Emphasis);
+
+ for fragment in label {
+ match fragment.style {
+ DisplayTextStyle::Regular => fragment.content.fmt(f)?,
+ DisplayTextStyle::Emphasis => emphasis_style.paint(&fragment.content, f)?,
+ }
+ }
+ Ok(())
+ }
+
+ fn format_annotation(
+ &self,
+ annotation: &Annotation<'_>,
+ continuation: bool,
+ in_source: bool,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ let color = self.get_annotation_style(&annotation.annotation_type);
+ let formatted_len = if let Some(id) = &annotation.id {
+ 2 + id.len() + Self::annotation_type_len(&annotation.annotation_type)
+ } else {
+ Self::annotation_type_len(&annotation.annotation_type)
+ };
+
+ if continuation {
+ format_repeat_char(' ', formatted_len + 2, f)?;
+ return self.format_label(&annotation.label, f);
+ }
+ if formatted_len == 0 {
+ self.format_label(&annotation.label, f)
+ } else {
+ color.paint_fn(
+ Box::new(|f| {
+ Self::format_annotation_type(&annotation.annotation_type, f)?;
+ if let Some(id) = &annotation.id {
+ f.write_char('[')?;
+ f.write_str(id)?;
+ f.write_char(']')?;
+ }
+ Ok(())
+ }),
+ f,
+ )?;
+ if !is_annotation_empty(annotation) {
+ if in_source {
+ color.paint_fn(
+ Box::new(|f| {
+ f.write_str(": ")?;
+ self.format_label(&annotation.label, f)
+ }),
+ f,
+ )?;
+ } else {
+ f.write_str(": ")?;
+ self.format_label(&annotation.label, f)?;
+ }
+ }
+ Ok(())
+ }
+ }
+
+ #[inline]
+ fn format_source_line(
+ &self,
+ line: &DisplaySourceLine<'_>,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ match line {
+ DisplaySourceLine::Empty => Ok(()),
+ DisplaySourceLine::Content { text, .. } => {
+ f.write_char(' ')?;
+ text.fmt(f)
+ }
+ DisplaySourceLine::Annotation {
+ range,
+ annotation,
+ annotation_type,
+ annotation_part,
+ } => {
+ let indent_char = match annotation_part {
+ DisplayAnnotationPart::Standalone => ' ',
+ DisplayAnnotationPart::LabelContinuation => ' ',
+ DisplayAnnotationPart::Consequitive => ' ',
+ DisplayAnnotationPart::MultilineStart => '_',
+ DisplayAnnotationPart::MultilineEnd => '_',
+ };
+ let mark = match annotation_type {
+ DisplayAnnotationType::Error => '^',
+ DisplayAnnotationType::Warning => '-',
+ DisplayAnnotationType::Info => '-',
+ DisplayAnnotationType::Note => '-',
+ DisplayAnnotationType::Help => '-',
+ DisplayAnnotationType::None => ' ',
+ };
+ let color = self.get_annotation_style(annotation_type);
+ let indent_length = match annotation_part {
+ DisplayAnnotationPart::LabelContinuation => range.1,
+ DisplayAnnotationPart::Consequitive => range.1,
+ _ => range.0,
+ };
+
+ color.paint_fn(
+ Box::new(|f| {
+ format_repeat_char(indent_char, indent_length + 1, f)?;
+ format_repeat_char(mark, range.1 - indent_length, f)
+ }),
+ f,
+ )?;
+
+ if !is_annotation_empty(&annotation) {
+ f.write_char(' ')?;
+ color.paint_fn(
+ Box::new(|f| {
+ self.format_annotation(
+ annotation,
+ annotation_part == &DisplayAnnotationPart::LabelContinuation,
+ true,
+ f,
+ )
+ }),
+ f,
+ )?;
+ }
+
+ Ok(())
+ }
+ }
+ }
+
+ #[inline]
+ fn format_raw_line(
+ &self,
+ line: &DisplayRawLine<'_>,
+ lineno_width: usize,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ match line {
+ DisplayRawLine::Origin {
+ path,
+ pos,
+ header_type,
+ } => {
+ let header_sigil = match header_type {
+ DisplayHeaderType::Initial => "-->",
+ DisplayHeaderType::Continuation => ":::",
+ };
+ let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
+
+ if let Some((col, row)) = pos {
+ format_repeat_char(' ', lineno_width, f)?;
+ lineno_color.paint(header_sigil, f)?;
+ f.write_char(' ')?;
+ path.fmt(f)?;
+ f.write_char(':')?;
+ col.fmt(f)?;
+ f.write_char(':')?;
+ row.fmt(f)
+ } else {
+ format_repeat_char(' ', lineno_width, f)?;
+ lineno_color.paint(header_sigil, f)?;
+ f.write_char(' ')?;
+ path.fmt(f)
+ }
+ }
+ DisplayRawLine::Annotation {
+ annotation,
+ source_aligned,
+ continuation,
+ } => {
+ if *source_aligned {
+ if *continuation {
+ format_repeat_char(' ', lineno_width + 3, f)?;
+ self.format_annotation(annotation, *continuation, false, f)
+ } else {
+ let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
+ format_repeat_char(' ', lineno_width, f)?;
+ f.write_char(' ')?;
+ lineno_color.paint("=", f)?;
+ f.write_char(' ')?;
+ self.format_annotation(annotation, *continuation, false, f)
+ }
+ } else {
+ self.format_annotation(annotation, *continuation, false, f)
+ }
+ }
+ }
+ }
+
+ #[inline]
+ fn format_line(
+ &self,
+ dl: &DisplayLine<'_>,
+ lineno_width: usize,
+ inline_marks_width: usize,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ match dl {
+ DisplayLine::Source {
+ lineno,
+ inline_marks,
+ line,
+ } => {
+ let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
+ if self.anonymized_line_numbers && lineno.is_some() {
+ lineno_color.paint_fn(
+ Box::new(|f| {
+ f.write_str(Self::ANONYMIZED_LINE_NUM)?;
+ f.write_str(" |")
+ }),
+ f,
+ )?;
+ } else {
+ lineno_color.paint_fn(
+ Box::new(|f| {
+ match lineno {
+ Some(n) => write!(f, "{:>width$}", n, width = lineno_width),
+ None => format_repeat_char(' ', lineno_width, f),
+ }?;
+ f.write_str(" |")
+ }),
+ f,
+ )?;
+ }
+ if *line != DisplaySourceLine::Empty {
+ if !inline_marks.is_empty() || 0 < inline_marks_width {
+ f.write_char(' ')?;
+ self.format_inline_marks(inline_marks, inline_marks_width, f)?;
+ }
+ self.format_source_line(line, f)?;
+ } else if !inline_marks.is_empty() {
+ f.write_char(' ')?;
+ self.format_inline_marks(inline_marks, inline_marks_width, f)?;
+ }
+ Ok(())
+ }
+ DisplayLine::Fold { inline_marks } => {
+ f.write_str("...")?;
+ if !inline_marks.is_empty() || 0 < inline_marks_width {
+ format_repeat_char(' ', lineno_width, f)?;
+ self.format_inline_marks(inline_marks, inline_marks_width, f)?;
+ }
+ Ok(())
+ }
+ DisplayLine::Raw(line) => self.format_raw_line(line, lineno_width, f),
+ }
+ }
+
+ fn format_inline_marks(
+ &self,
+ inline_marks: &[DisplayMark],
+ inline_marks_width: usize,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ format_repeat_char(' ', inline_marks_width - inline_marks.len(), f)?;
+ for mark in inline_marks {
+ self.get_annotation_style(&mark.annotation_type).paint_fn(
+ Box::new(|f| {
+ f.write_char(match mark.mark_type {
+ DisplayMarkType::AnnotationThrough => '|',
+ DisplayMarkType::AnnotationStart => '/',
+ })
+ }),
+ f,
+ )?;
+ }
+ Ok(())
+ }
+}