use std::ops::Range;
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub(crate) struct Id<'a> {
pub(crate) id: &'a str,
pub(crate) url: Option<&'a str>,
}
#[derive(Debug)]
pub struct Message<'a> {
pub(crate) level: Level,
pub(crate) id: Option<Id<'a>>,
pub(crate) title: &'a str,
pub(crate) snippets: Vec<Snippet<'a>>,
pub(crate) footer: Vec<Message<'a>>,
pub(crate) is_fixable: bool,
pub(crate) lineno_offset: usize,
}
impl<'a> Message<'a> {
pub fn id(mut self, id: &'a str) -> Self {
self.id = Some(Id { id, url: None });
self
}
pub fn id_with_url(mut self, id: &'a str, url: Option<&'a str>) -> Self {
self.id = Some(Id { id, url });
self
}
pub fn snippet(mut self, slice: Snippet<'a>) -> Self {
self.snippets.push(slice);
self
}
pub fn snippets(mut self, slice: impl IntoIterator<Item = Snippet<'a>>) -> Self {
self.snippets.extend(slice);
self
}
pub fn footer(mut self, footer: Message<'a>) -> Self {
self.footer.push(footer);
self
}
pub fn footers(mut self, footer: impl IntoIterator<Item = Message<'a>>) -> Self {
self.footer.extend(footer);
self
}
pub fn is_fixable(mut self, yes: bool) -> Self {
self.is_fixable = yes;
self
}
pub fn lineno_offset(mut self, offset: usize) -> Self {
self.lineno_offset = offset;
self
}
}
#[derive(Debug)]
pub struct Snippet<'a> {
pub(crate) origin: Option<&'a str>,
pub(crate) line_start: usize,
pub(crate) source: &'a str,
pub(crate) annotations: Vec<Annotation<'a>>,
pub(crate) fold: bool,
pub(crate) cell_index: Option<usize>,
}
impl<'a> Snippet<'a> {
pub fn source(source: &'a str) -> Self {
Self {
origin: None,
line_start: 1,
source,
annotations: vec![],
fold: false,
cell_index: None,
}
}
pub fn line_start(mut self, line_start: usize) -> Self {
self.line_start = line_start;
self
}
pub fn origin(mut self, origin: &'a str) -> Self {
self.origin = Some(origin);
self
}
pub fn annotation(mut self, annotation: Annotation<'a>) -> Self {
self.annotations.push(annotation);
self
}
pub fn annotations(mut self, annotation: impl IntoIterator<Item = Annotation<'a>>) -> Self {
self.annotations.extend(annotation);
self
}
pub fn fold(mut self, fold: bool) -> Self {
self.fold = fold;
self
}
pub fn cell_index(mut self, index: Option<usize>) -> Self {
self.cell_index = index;
self
}
}
#[derive(Debug)]
pub struct Annotation<'a> {
pub(crate) range: Range<usize>,
pub(crate) label: Option<&'a str>,
pub(crate) level: Level,
pub(crate) is_file_level: bool,
}
impl<'a> Annotation<'a> {
pub fn label(mut self, label: &'a str) -> Self {
self.label = Some(label);
self
}
pub fn hide_snippet(mut self, yes: bool) -> Self {
self.is_file_level = yes;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Level {
None,
Error,
Warning,
Info,
Note,
Help,
}
impl Level {
pub fn title(self, title: &str) -> Message<'_> {
Message {
level: self,
id: None,
title,
snippets: vec![],
footer: vec![],
is_fixable: false,
lineno_offset: 0,
}
}
pub fn span<'a>(self, span: Range<usize>) -> Annotation<'a> {
Annotation {
range: span,
label: None,
level: self,
is_file_level: false,
}
}
}