Skip to content

Commit

Permalink
Merge pull request #185 from 01mf02/codesnake
Browse files Browse the repository at this point in the history
Replace ariadne with codesnake.
  • Loading branch information
01mf02 authored Jun 18, 2024
2 parents a02df55 + ccdab6f commit f2b92fd
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 129 deletions.
35 changes: 20 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions jaq-play/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ jaq-parse = { version = "1.0.0", path = "../jaq-parse" }
jaq-interpret = { version = "1.2.0", path = "../jaq-interpret" }
jaq-core = { version = "1.2.0", path = "../jaq-core" }
jaq-std = { version = "1.2.0", path = "../jaq-std" }
ariadne = "0.4.0"
aho-corasick = "1.1.2"
codesnake = { version = "0.1" }
chumsky = { version = "0.9.0", default-features = false }
hifijson = "0.2"
log = "0.4.17"
unicode-width = "0.1.13"

console_log = { version = "1.0", features = ["color"] }
getrandom = { version = "0.2", features = ["js"] }
wasm-bindgen = { version = "0.2" }
web-sys = { version = "0.3", features = ["DedicatedWorkerGlobalScope"] }
js-sys = { version = "0.3" }
aho-corasick = "1.1.2"
105 changes: 67 additions & 38 deletions jaq-play/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,14 @@ pub fn run(filter: &str, input: &str, settings: &JsValue, scope: &Scope) {
Ok(()) => (),
Err(Error::Chumsky(errs)) => {
for e in errs {
let mut buf = Vec::new();
let cache = ariadne::Source::from(filter);
report(e).write(cache, &mut buf).unwrap();
let s = String::from_utf8(buf).unwrap();
scope.post_message(&format!("⚠️ Parse {s}").into()).unwrap();
scope
.post_message(&format!("⚠️ Parse error: {}", report(filter, &e)).into())
.unwrap();
}
}
Err(Error::Hifijson(e)) => {
scope
.post_message(&format!("⚠️ Parse Error: {e}").into())
.post_message(&format!("⚠️ Parse error: {e}").into())
.unwrap();
}
Err(Error::Jaq(e)) => {
Expand Down Expand Up @@ -296,14 +294,33 @@ fn parse(filter_str: &str, vars: Vec<String>) -> Result<Filter, Vec<ChumskyError
}
}

fn report<'a>(e: chumsky::error::Simple<String>) -> ariadne::Report<'a> {
use ariadne::{Color, Fmt, Label, Report, ReportKind};
#[derive(Debug)]
struct Report<'a> {
code: &'a str,
message: String,
labels: Vec<(core::ops::Range<usize>, String, Color)>,
}

#[derive(Clone, Debug)]
enum Color {
Yellow,
Red,
}

impl Color {
fn apply(&self, d: impl Display) -> String {
let mut color = format!("{self:?}");
color.make_ascii_lowercase();
format!("<span class={color}>{d}</span>",)
}
}

fn report<'a>(code: &'a str, e: &chumsky::error::Simple<String>) -> Report<'a> {
use chumsky::error::SimpleReason;

let (red, yellow) = (Color::Unset, Color::Unset);
let config = ariadne::Config::default().with_color(false);
let eof = || "end of input".to_string();

let msg = if let SimpleReason::Custom(msg) = e.reason() {
let message = if let SimpleReason::Custom(msg) = e.reason() {
msg.clone()
} else {
let found = if e.found().is_some() {
Expand All @@ -319,41 +336,53 @@ fn report<'a>(e: chumsky::error::Simple<String>) -> ariadne::Report<'a> {
let expected = if e.expected().len() == 0 {
"something else".to_string()
} else {
e.expected()
.map(|expected| match expected {
Some(expected) => expected.to_string(),
None => "end of input".to_string(),
})
.collect::<Vec<_>>()
.join(", ")
let f = |e: &Option<String>| e.as_ref().map_or_else(eof, |e| e.to_string());
e.expected().map(f).collect::<Vec<_>>().join(", ")
};
format!("{found}{when}, expected {expected}",)
};

let label = if let SimpleReason::Custom(msg) = e.reason() {
msg.clone()
} else {
format!(
"Unexpected {}",
e.found()
.map(|c| format!("token {}", c.fg(red)))
.unwrap_or_else(|| "end of input".to_string())
)
let token = |c: &String| format!("token {}", Color::Red.apply(c));
format!("Unexpected {}", e.found().map_or_else(eof, token))
};

let report = Report::build(ReportKind::Error, (), e.span().start)
.with_message(msg)
.with_label(Label::new(e.span()).with_message(label).with_color(red));

let report = match e.reason() {
SimpleReason::Unclosed { span, delimiter } => report.with_label(
Label::new(span.clone())
.with_message(format!("Unclosed delimiter {}", delimiter.fg(yellow)))
.with_color(yellow),
),
SimpleReason::Unexpected => report,
SimpleReason::Custom(_) => report,
// convert character indices to byte offsets
let char_to_byte = |i| {
code.char_indices()
.map(|(i, _c)| i)
.chain([code.len(), code.len()])
.nth(i)
.unwrap()
};
let conv = |span: &core::ops::Range<_>| char_to_byte(span.start)..char_to_byte(span.end);
let mut labels = Vec::from([(conv(&e.span()), label, Color::Red)]);

if let SimpleReason::Unclosed { span, delimiter } = e.reason() {
let text = format!("Unclosed delimiter {}", Color::Yellow.apply(delimiter));
labels.insert(0, (conv(span), text, Color::Yellow));
}
Report {
code,
message,
labels,
}
}

report.with_config(config).finish()
impl Display for Report<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
use codesnake::{Block, CodeWidth, Label, LineIndex};
let idx = LineIndex::new(self.code);
let labels = self.labels.clone().into_iter().map(|(range, text, color)| {
Label::new(range, text).with_style(move |s| color.apply(s).to_string())
});
let block = Block::new(&idx, labels).unwrap().map_code(|c| {
let c = c.replace('\t', " ");
let w = unicode_width::UnicodeWidthStr::width(&*c);
CodeWidth::new(c, core::cmp::max(w, 1))
});
writeln!(f, "{}", self.message)?;
write!(f, "{}\n{}{}", block.prologue(), block, block.epilogue())
}
}
3 changes: 3 additions & 0 deletions jaq-play/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ textarea {
.null { color: magenta; }
.key { color: red; }

.red { color: #dc322f; }
.yellow { color: #b58900; }


.settings { display: inline-block; }

Expand Down
4 changes: 3 additions & 1 deletion jaq/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ jaq-parse = { version = "1.0.0", path = "../jaq-parse" }
jaq-interpret = { version = "1.2.0", path = "../jaq-interpret" }
jaq-core = { version = "1.2.0", path = "../jaq-core" }
jaq-std = { version = "1.2.0", path = "../jaq-std" }
ariadne = "0.4.0"
atty = "0.2"
chumsky = { version = "0.9.0", default-features = false }
codesnake = { version = "0.1" }
clap = { version = "4.0.0", features = ["derive"] }
colored_json = "3.0.1"
env_logger = { version = "0.10.0", default-features = false }
Expand All @@ -31,3 +31,5 @@ memmap2 = "0.9"
mimalloc = { version = "0.1.29", default-features = false, optional = true }
serde_json = { version = "1.0.81", features = [ "arbitrary_precision", "preserve_order" ] }
tempfile = "3.3.0"
unicode-width = "0.1.13"
yansi = "1.0.1"
Loading

0 comments on commit f2b92fd

Please sign in to comment.