error with source printing

This commit is contained in:
Robin Appelman 2020-12-13 18:21:12 +01:00
commit bf1edefb25
4 changed files with 21 additions and 17 deletions

View file

@ -19,6 +19,6 @@ fn main() {
match parse(source) { match parse(source) {
Ok(result) => print!("{:#?}", result), Ok(result) => print!("{:#?}", result),
Err(err) => eprint!("{}", err), Err(err) => eprint!("{}", err.with_source(source)),
} }
} }

View file

@ -14,7 +14,7 @@ use thiserror::Error;
/// An error and related source span /// An error and related source span
/// ///
/// You can pretty-print the error with the offending source by using `display_with_source` /// You can pretty-print the error with the offending source by using `with_source`
/// ///
/// ## Example /// ## Example
/// ///
@ -42,6 +42,14 @@ impl<T: Error + Debug> SpannedError<T> {
pub fn error(&self) -> &T { pub fn error(&self) -> &T {
&self.error &self.error
} }
pub fn with_source(self, source: &str) -> SourceSpannedError<T> {
SourceSpannedError {
span: self.span,
error: self.error,
source,
}
}
} }
impl<T: Error + Debug + 'static> Error for SpannedError<T> { impl<T: Error + Debug + 'static> Error for SpannedError<T> {
@ -56,17 +64,23 @@ impl<T: Error + Debug> Display for SpannedError<T> {
} }
} }
pub struct SourceSpannedError<'source, T> {
span: Span,
error: T,
source: &'source str,
}
const METRICS: DefaultMetrics = DefaultMetrics::with_tab_stop(4); const METRICS: DefaultMetrics = DefaultMetrics::with_tab_stop(4);
impl<T: Error + Debug> SpannedError<T> { impl<'source, T: Error + Debug> Display for SourceSpannedError<'source, T> {
pub fn display_with_source(&self, source: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let start = get_position(source, self.span.start); let start = get_position(self.source, self.span.start);
let end = get_position(source, self.span.end); let end = get_position(self.source, self.span.end);
let span = SourceSpan::new(start, end, end.next_line()); let span = SourceSpan::new(start, end, end.next_line());
let mut fmt = Formatter::with_margin_color(Color::Blue); let mut fmt = Formatter::with_margin_color(Color::Blue);
let buffer = SourceBuffer::new( let buffer = SourceBuffer::new(
source.chars().map(|char| Result::<char, ()>::Ok(char)), self.source.chars().map(|char| Result::<char, ()>::Ok(char)),
Position::default(), Position::default(),
METRICS, METRICS,
); );

View file

@ -186,14 +186,6 @@ impl<'source> TokenStream<'source> {
pub fn new(lexer: Lexer<'source, Token>) -> Self { pub fn new(lexer: Lexer<'source, Token>) -> Self {
TokenStream { lexer } TokenStream { lexer }
} }
pub fn source(&self) -> &'source str {
self.lexer.source()
}
pub fn span(&self) -> Span {
self.lexer.span()
}
} }
impl<'source> Iterator for TokenStream<'source> { impl<'source> Iterator for TokenStream<'source> {

View file

@ -30,14 +30,12 @@ pub fn parse(source: &str) -> Result<Value, SpannedError<ParseError>> {
} }
pub struct Parser<'source> { pub struct Parser<'source> {
source: &'source str,
tokens: TokenStream<'source>, tokens: TokenStream<'source>,
} }
impl<'source> Parser<'source> { impl<'source> Parser<'source> {
pub fn new(source: &'source str) -> Self { pub fn new(source: &'source str) -> Self {
Parser { Parser {
source,
tokens: TokenStream::new(Token::lexer(source)), tokens: TokenStream::new(Token::lexer(source)),
} }
} }