92 lines
2.9 KiB
Rust
92 lines
2.9 KiB
Rust
|
|
|
|
use codespan_reporting::{
|
|
diagnostic::{Diagnostic, Label},
|
|
files::SimpleFiles,
|
|
};
|
|
|
|
use crate::Span;
|
|
|
|
#[derive(Debug)]
|
|
pub struct Errors {
|
|
pub kind: ErrorKind,
|
|
pub locs: Vec<Span>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum ErrorKind {
|
|
InvalidToken,
|
|
SyntaxError(SyntaxErrorKind),
|
|
CommandNotFound,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum SyntaxErrorKind {
|
|
/// `MissingStreamer` means, that the pipeline starts with a Pipe (`|`), so it has no streamer as input in front of it.
|
|
MissingStreamer,
|
|
/// `MissingSink` means, that the pipeline ends with a Pipe (`|`), meaning that the output can't go anywhere
|
|
MissingSink,
|
|
/// This indicates a missing filter somewhere in the pipeline, meaning that there's 2 pipes after one another
|
|
MissingFilter,
|
|
/// A literal cannot be a sink
|
|
LiteralAsSink,
|
|
/// A literal can't be a filter either
|
|
LiteralAsFilter,
|
|
/// A literal acting as streamer cannot take arguments
|
|
LiteralWithArgs,
|
|
}
|
|
|
|
impl Errors {
|
|
pub fn new(kind: ErrorKind, locs: Vec<Span>) -> Self {
|
|
Self { kind, locs }
|
|
}
|
|
pub fn new_single(kind: ErrorKind, loc: Span) -> Self {
|
|
Self {
|
|
kind,
|
|
locs: vec![loc],
|
|
}
|
|
}
|
|
pub fn into_diag(
|
|
&self,
|
|
file_id: usize,
|
|
_file_db: &SimpleFiles<&str, String>,
|
|
) -> Diagnostic<usize> {
|
|
let Errors { kind, locs } = self;
|
|
|
|
match kind {
|
|
ErrorKind::InvalidToken => simple_diag(locs.clone(), file_id, "invalid tokens"),
|
|
ErrorKind::SyntaxError(syntax_error) => match syntax_error {
|
|
SyntaxErrorKind::MissingStreamer => simple_diag(
|
|
locs.clone(),
|
|
file_id,
|
|
"pipeline is missing an input provider",
|
|
),
|
|
SyntaxErrorKind::MissingSink => {
|
|
simple_diag(locs.clone(), file_id, "pipeline is missing a sink")
|
|
}
|
|
SyntaxErrorKind::MissingFilter => {
|
|
simple_diag(locs.clone(), file_id, "missing filters in pipeline")
|
|
}
|
|
SyntaxErrorKind::LiteralAsSink => {
|
|
simple_diag(locs.clone(), file_id, "pipelines can't end in a literal")
|
|
}
|
|
SyntaxErrorKind::LiteralAsFilter => {
|
|
simple_diag(locs.clone(), file_id, "literals can't filter data")
|
|
}
|
|
SyntaxErrorKind::LiteralWithArgs => {
|
|
simple_diag(locs.clone(), file_id, "literals can't take arguments")
|
|
}
|
|
},
|
|
ErrorKind::CommandNotFound => simple_diag(locs.clone(), file_id, "command not found"),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn simple_diag(spans: Vec<Span>, file_id: usize, msg: &str) -> Diagnostic<usize> {
|
|
Diagnostic::error().with_message(msg).with_labels(
|
|
spans
|
|
.into_iter()
|
|
.map(|span| Label::primary(file_id, span))
|
|
.collect(),
|
|
)
|
|
}
|