2019-05-16 00:58:44 +02:00
|
|
|
#[allow(unused)]
|
2019-05-15 20:14:51 +02:00
|
|
|
use crate::prelude::*;
|
2019-06-22 05:43:37 +02:00
|
|
|
|
|
|
|
use crate::parser::Span;
|
2019-05-10 18:59:12 +02:00
|
|
|
use derive_new::new;
|
2019-06-08 00:35:07 +02:00
|
|
|
use language_reporting::{Diagnostic, Label, Severity};
|
2019-06-01 07:50:16 +02:00
|
|
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
2019-05-10 18:59:12 +02:00
|
|
|
|
2019-06-01 07:50:16 +02:00
|
|
|
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Serialize, Deserialize)]
|
2019-05-30 06:19:46 +02:00
|
|
|
pub enum ShellError {
|
|
|
|
String(StringError),
|
2019-06-03 07:11:21 +02:00
|
|
|
TypeError(String),
|
|
|
|
MissingProperty { subpath: String, expr: String },
|
2019-06-08 00:35:07 +02:00
|
|
|
Diagnostic(ShellDiagnostic),
|
2019-05-13 19:30:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
crate fn parse_error(
|
2019-06-22 05:43:37 +02:00
|
|
|
error: nom::Err<(nom_locate::LocatedSpan<&str>, nom::error::ErrorKind)>,
|
2019-05-30 06:19:46 +02:00
|
|
|
) -> ShellError {
|
|
|
|
use language_reporting::*;
|
|
|
|
|
|
|
|
match error {
|
2019-06-22 05:43:37 +02:00
|
|
|
nom::Err::Incomplete(_) => unreachable!(),
|
|
|
|
nom::Err::Failure(span) | nom::Err::Error(span) => {
|
|
|
|
let diagnostic =
|
|
|
|
Diagnostic::new(Severity::Error, format!("{:?}", span))
|
|
|
|
.with_label(Label::new_primary(Span::from(span.0)));
|
2019-05-30 06:19:46 +02:00
|
|
|
|
2019-06-08 00:35:07 +02:00
|
|
|
ShellError::diagnostic(diagnostic)
|
2019-06-22 05:43:37 +02:00
|
|
|
// nom::Context::Code(span, kind) => {
|
|
|
|
// let diagnostic =
|
|
|
|
// Diagnostic::new(Severity::Error, format!("{}", kind.description()))
|
|
|
|
// .with_label(Label::new_primary(Span::from(span)));
|
|
|
|
|
|
|
|
// ShellError::diagnostic(diagnostic)
|
|
|
|
// }
|
2019-05-30 06:19:46 +02:00
|
|
|
}
|
2019-06-22 05:43:37 +02:00
|
|
|
// ParseError::UnrecognizedToken {
|
|
|
|
// token: (start, SpannedToken { token, .. }, end),
|
|
|
|
// expected,
|
|
|
|
// } => {
|
|
|
|
// let diagnostic = Diagnostic::new(
|
|
|
|
// Severity::Error,
|
|
|
|
// format!("Unexpected {:?}, expected {:?}", token, expected),
|
|
|
|
// )
|
|
|
|
// .with_label(Label::new_primary(Span::from((start, end))));
|
|
|
|
|
|
|
|
// ShellError::diagnostic(diagnostic)
|
|
|
|
// }
|
|
|
|
// ParseError::User { error } => error,
|
|
|
|
// other => ShellError::string(format!("{:?}", other)),
|
2019-05-30 06:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-08 00:35:07 +02:00
|
|
|
crate fn diagnostic(diagnostic: Diagnostic<Span>) -> ShellError {
|
|
|
|
ShellError::Diagnostic(ShellDiagnostic { diagnostic })
|
|
|
|
}
|
|
|
|
|
|
|
|
crate fn labeled_error(
|
|
|
|
msg: impl Into<String>,
|
|
|
|
label: impl Into<String>,
|
|
|
|
span: Span,
|
|
|
|
) -> ShellError {
|
|
|
|
ShellError::diagnostic(
|
|
|
|
Diagnostic::new(Severity::Error, msg.into())
|
|
|
|
.with_label(Label::new_primary(span).with_message(label.into())),
|
|
|
|
)
|
2019-05-30 06:19:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-15 20:36:17 +02:00
|
|
|
crate fn maybe_labeled_error(
|
|
|
|
msg: impl Into<String>,
|
|
|
|
label: impl Into<String>,
|
|
|
|
span: Option<Span>,
|
|
|
|
) -> ShellError {
|
|
|
|
match span {
|
|
|
|
Some(span) => ShellError::diagnostic(
|
|
|
|
Diagnostic::new(Severity::Error, msg.into())
|
|
|
|
.with_label(Label::new_primary(span).with_message(label.into())),
|
|
|
|
),
|
|
|
|
None => ShellError::string(msg),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-13 19:30:51 +02:00
|
|
|
crate fn string(title: impl Into<String>) -> ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
ShellError::String(StringError::new(title.into(), Value::nothing()))
|
2019-05-13 19:30:51 +02:00
|
|
|
}
|
2019-05-15 20:14:51 +02:00
|
|
|
|
2019-06-04 23:42:31 +02:00
|
|
|
crate fn unimplemented(title: impl Into<String>) -> ShellError {
|
|
|
|
ShellError::string(&format!("Unimplemented: {}", title.into()))
|
|
|
|
}
|
|
|
|
|
2019-06-22 05:43:37 +02:00
|
|
|
crate fn unexpected(title: impl Into<String>) -> ShellError {
|
|
|
|
ShellError::string(&format!("Unexpected: {}", title.into()))
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:14:51 +02:00
|
|
|
crate fn copy_error(&self) -> ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
self.clone()
|
2019-05-15 20:14:51 +02:00
|
|
|
}
|
2019-05-30 06:19:46 +02:00
|
|
|
}
|
2019-05-16 23:43:36 +02:00
|
|
|
|
2019-05-30 06:19:46 +02:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ShellDiagnostic {
|
|
|
|
crate diagnostic: Diagnostic<Span>,
|
|
|
|
}
|
|
|
|
|
2019-06-04 23:42:31 +02:00
|
|
|
impl ShellDiagnostic {
|
2019-06-06 08:34:59 +02:00
|
|
|
#[allow(unused)]
|
2019-06-04 23:42:31 +02:00
|
|
|
crate fn simple_diagnostic(
|
|
|
|
span: impl Into<Span>,
|
|
|
|
source: impl Into<String>,
|
|
|
|
) -> ShellDiagnostic {
|
|
|
|
use language_reporting::*;
|
|
|
|
|
|
|
|
let span = span.into();
|
|
|
|
let source = source.into();
|
|
|
|
|
|
|
|
let diagnostic =
|
|
|
|
Diagnostic::new(Severity::Error, "Parse error").with_label(Label::new_primary(span));
|
|
|
|
|
|
|
|
ShellDiagnostic { diagnostic }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-30 06:19:46 +02:00
|
|
|
impl PartialEq for ShellDiagnostic {
|
|
|
|
fn eq(&self, _other: &ShellDiagnostic) -> bool {
|
|
|
|
false
|
2019-05-16 23:43:36 +02:00
|
|
|
}
|
2019-05-10 18:59:12 +02:00
|
|
|
}
|
|
|
|
|
2019-05-30 06:19:46 +02:00
|
|
|
impl Eq for ShellDiagnostic {}
|
|
|
|
|
|
|
|
impl std::cmp::PartialOrd for ShellDiagnostic {
|
|
|
|
fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
|
|
|
|
Some(std::cmp::Ordering::Less)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::cmp::Ord for ShellDiagnostic {
|
|
|
|
fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
|
|
|
|
std::cmp::Ordering::Less
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Serialize for ShellDiagnostic {
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
|
|
|
{
|
|
|
|
"<diagnostic>".serialize(serializer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-01 07:50:16 +02:00
|
|
|
impl Deserialize<'de> for ShellDiagnostic {
|
|
|
|
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
Ok(ShellDiagnostic {
|
|
|
|
diagnostic: Diagnostic::new(
|
|
|
|
language_reporting::Severity::Error,
|
|
|
|
"deserialize not implemented for ShellDiagnostic",
|
|
|
|
),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, new, Clone, Serialize, Deserialize)]
|
2019-05-30 06:19:46 +02:00
|
|
|
pub struct StringError {
|
|
|
|
title: String,
|
|
|
|
error: Value,
|
|
|
|
}
|
|
|
|
|
2019-05-10 18:59:12 +02:00
|
|
|
impl std::fmt::Display for ShellError {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
2019-05-30 06:19:46 +02:00
|
|
|
match self {
|
|
|
|
ShellError::String(s) => write!(f, "{}", &s.title),
|
2019-06-03 07:11:21 +02:00
|
|
|
ShellError::TypeError { .. } => write!(f, "TypeError"),
|
|
|
|
ShellError::MissingProperty { .. } => write!(f, "MissingProperty"),
|
2019-06-08 00:35:07 +02:00
|
|
|
ShellError::Diagnostic(_) => write!(f, "<diagnostic>"),
|
2019-05-30 06:19:46 +02:00
|
|
|
}
|
2019-05-10 18:59:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for ShellError {}
|
|
|
|
|
|
|
|
impl std::convert::From<std::io::Error> for ShellError {
|
|
|
|
fn from(input: std::io::Error) -> ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
ShellError::String(StringError {
|
2019-05-10 18:59:12 +02:00
|
|
|
title: format!("{}", input),
|
2019-05-13 19:30:51 +02:00
|
|
|
error: Value::nothing(),
|
2019-05-30 06:19:46 +02:00
|
|
|
})
|
2019-05-10 18:59:12 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-24 06:34:43 +02:00
|
|
|
|
|
|
|
impl std::convert::From<futures_sink::VecSinkError> for ShellError {
|
|
|
|
fn from(_input: futures_sink::VecSinkError) -> ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
ShellError::String(StringError {
|
2019-05-24 06:34:43 +02:00
|
|
|
title: format!("Unexpected Vec Sink Error"),
|
|
|
|
error: Value::nothing(),
|
2019-05-30 06:19:46 +02:00
|
|
|
})
|
2019-05-24 06:34:43 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-24 09:29:16 +02:00
|
|
|
|
|
|
|
impl std::convert::From<subprocess::PopenError> for ShellError {
|
|
|
|
fn from(input: subprocess::PopenError) -> ShellError {
|
2019-05-30 06:19:46 +02:00
|
|
|
ShellError::String(StringError {
|
2019-05-24 09:29:16 +02:00
|
|
|
title: format!("{}", input),
|
|
|
|
error: Value::nothing(),
|
2019-05-30 06:19:46 +02:00
|
|
|
})
|
2019-05-24 09:29:16 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-26 08:54:41 +02:00
|
|
|
|
2019-06-22 05:43:37 +02:00
|
|
|
// impl std::convert::From<nom::Err<(&str, nom::ErrorKind)>> for ShellError {
|
|
|
|
// fn from(input: nom::Err<(&str, nom::ErrorKind)>) -> ShellError {
|
|
|
|
// ShellError::String(StringError {
|
|
|
|
// title: format!("{:?}", input),
|
|
|
|
// error: Value::nothing(),
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
// }
|
2019-06-01 07:50:16 +02:00
|
|
|
|
|
|
|
impl std::convert::From<toml::ser::Error> for ShellError {
|
|
|
|
fn from(input: toml::ser::Error) -> ShellError {
|
|
|
|
ShellError::String(StringError {
|
|
|
|
title: format!("{:?}", input),
|
|
|
|
error: Value::nothing(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|