difftreelog
feat fancy syntax errors
in: master
2 files changed
cmds/jsonnet/Cargo.tomldiffbeforeafterboth889[dependencies]9[dependencies]10jsonnet-evaluator = { path = "../../crates/jsonnet-evaluator" }10jsonnet-evaluator = { path = "../../crates/jsonnet-evaluator" }11jsonnet-parser = { path = "../../crates/jsonnet-parser" }11annotate-snippets = "0.8.0"12annotate-snippets = "0.8.0"121313[dependencies.clap]14[dependencies.clap]cmds/jsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jsonnet/src/main.rs
+++ b/cmds/jsonnet/src/main.rs
@@ -4,7 +4,7 @@
use jsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val};
use location::{offset_to_location, CodeLocation};
use std::env::current_dir;
-use std::str::FromStr;
+use std::{path::PathBuf, str::FromStr};
enum Format {
None,
@@ -87,12 +87,11 @@
}
let mut input = current_dir().unwrap();
input.push(opts.input.clone());
- evaluator
- .add_file(
- input.clone(),
- String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap(),
- )
- .unwrap();
+ let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();
+ if let Err(e) = evaluator.add_file(input.clone(), code_string.clone()) {
+ print_syntax_error(e, &input, &code_string);
+ std::process::exit(2);
+ }
let result = evaluator.evaluate_file(&input);
match result {
Ok(v) => {
@@ -148,6 +147,42 @@
print_trace(&(err.1), evaluator, &opts);
}
+fn print_syntax_error(error: jsonnet_parser::ParseError, file: &PathBuf, code: &str) {
+ use annotate_snippets::{
+ display_list::{DisplayList, FormatOptions},
+ snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
+ };
+ //&("Expected: ".to_owned() + error.expected)
+ let origin = file.to_str().unwrap();
+ let error_message = format!("Expected: {}", error.expected);
+ let snippet = Snippet {
+ opt: FormatOptions {
+ color: true,
+ ..Default::default()
+ },
+ title: Some(Annotation {
+ label: Some(&error_message),
+ id: None,
+ annotation_type: AnnotationType::Error,
+ }),
+ footer: vec![],
+ slices: vec![Slice {
+ source: &code,
+ line_start: 1,
+ origin: Some(origin),
+ fold: false,
+ annotations: vec![SourceAnnotation {
+ label: "At this position",
+ annotation_type: AnnotationType::Error,
+ range: (error.location.offset, error.location.offset + 1),
+ }],
+ }],
+ };
+
+ let dl = DisplayList::from(snippet);
+ println!("{}", dl);
+}
+
fn print_trace(trace: &StackTrace, evaluator: EvaluationState, opts: &Opts) {
use annotate_snippets::{
display_list::{DisplayList, FormatOptions},