diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89809f5..87baaab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@cargo-hack - name: Default features - run: cargo hack check --feature-powerset --locked --rust-version --ignore-private --workspace --all-targets + run: cargo hack check --feature-powerset --locked --rust-version --ignore-private --workspace --lib --bins lockfile: runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index 226775f..244fffd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "annotate-snippets" version = "0.11.4" @@ -24,9 +18,10 @@ dependencies = [ "annotate-snippets", "anstream 0.6.15", "anstyle", - "criterion", "difference", + "divan", "glob", + "memchr", "serde", "snapbox", "toml", @@ -131,10 +126,10 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.3.0" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" @@ -146,51 +141,12 @@ dependencies = [ "serde", ] -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "clap" version = "4.3.24" @@ -212,6 +168,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -239,83 +196,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] -name = "criterion" -version = "0.5.1" +name = "condtype" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "is-terminal", - "itertools", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] +checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" [[package]] -name = "criterion-plot" -version = "0.5.0" +name = "difference" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] -name = "crossbeam-deque" -version = "0.8.5" +name = "divan" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "a0d567df2c9c2870a43f3f2bd65aaeb18dbce1c18f217c3e564b4fbaeb3ee56c" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "cfg-if", + "clap", + "condtype", + "divan-macros", + "libc", + "regex-lite", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.18" +name = "divan-macros" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "27540baf49be0d484d8f0130d7d8da3011c32a44d4fc873368154f1510e574a2" dependencies = [ - "crossbeam-utils", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - -[[package]] -name = "either" -version = "1.12.0" +name = "errno" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] [[package]] name = "escape8259" @@ -357,15 +282,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "half" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" -dependencies = [ - "crunchy", -] - [[package]] name = "heck" version = "0.4.1" @@ -404,6 +320,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "is-terminal" version = "0.4.12" @@ -424,30 +351,12 @@ dependencies = [ "is-terminal", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -472,6 +381,12 @@ dependencies = [ "threadpool", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "log" version = "0.4.21" @@ -480,9 +395,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "normalize-line-endings" @@ -490,15 +405,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.16.0" @@ -515,12 +421,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "os_pipe" version = "1.2.0" @@ -531,34 +431,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "plotters" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" - -[[package]] -name = "plotters-svg" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" -dependencies = [ - "plotters-backend", -] - [[package]] name = "proc-macro2" version = "1.0.85" @@ -577,26 +449,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "regex" version = "1.10.4" @@ -620,12 +472,32 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -739,6 +611,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -758,16 +640,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "toml" version = "0.5.11" @@ -831,70 +703,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "winapi-util" version = "0.1.8" diff --git a/Cargo.toml b/Cargo.toml index d323686..42ae1b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,13 +25,14 @@ maintenance = { status = "actively-developed" } [dependencies] anstyle = "1.0.4" +memchr = { version = "2.7.4", optional = true } unicode-width = "0.1.11" [dev-dependencies] annotate-snippets = { path = ".", features = ["testing-colors"] } anstream = "0.6.13" -criterion = "0.5.1" difference = "2.0.0" +divan = "0.1.14" glob = "0.3.1" serde = { version = "1.0.199", features = ["derive"] } snapbox = { version = "0.6.0", features = ["diff", "term-svg", "cmd", "examples"] } @@ -39,7 +40,7 @@ toml = "0.5.11" tryfn = "0.2.1" [[bench]] -name = "simple" +name = "bench" harness = false [[test]] @@ -48,6 +49,7 @@ harness = false [features] default = [] +simd = ["memchr"] testing-colors = [] [lints.rust] diff --git a/benches/bench.rs b/benches/bench.rs new file mode 100644 index 0000000..9747954 --- /dev/null +++ b/benches/bench.rs @@ -0,0 +1,89 @@ +use annotate_snippets::{Level, Renderer, Snippet}; + +#[divan::bench] +fn simple() -> String { + let source = r#") -> Option { + for ann in annotations { + match (ann.range.0, ann.range.1) { + (None, None) => continue, + (Some(start), Some(end)) if start > end_index => continue, + (Some(start), Some(end)) if start >= start_index => { + let label = if let Some(ref label) = ann.label { + format!(" {}", label) + } else { + String::from("") + }; + + return Some(format!( + "{}{}{}", + " ".repeat(start - start_index), + "^".repeat(end - start), + label + )); + } + _ => continue, + } + }"#; + let message = Level::Error.title("mismatched types").id("E0308").snippet( + Snippet::source(source) + .line_start(51) + .origin("src/format.rs") + .annotation( + Level::Warning + .span(5..19) + .label("expected `Option` because of return type"), + ) + .annotation( + Level::Error + .span(26..724) + .label("expected enum `std::option::Option`"), + ), + ); + + let renderer = Renderer::plain(); + let rendered = renderer.render(message).to_string(); + rendered +} + +#[divan::bench(args=[0, 1, 10, 100, 1_000, 10_000, 100_000])] +fn fold(bencher: divan::Bencher<'_, '_>, context: usize) { + bencher + .with_inputs(|| { + let line = "012345678901234567890123456789"; + let mut input = String::new(); + for _ in 1..=context { + input.push_str(line); + input.push('\n'); + } + let span_start = input.len() + line.len(); + let span = span_start..span_start; + + input.push_str(line); + input.push('\n'); + for _ in 1..=context { + input.push_str(line); + input.push('\n'); + } + (input, span) + }) + .bench_values(|(input, span)| { + let message = Level::Error.title("mismatched types").id("E0308").snippet( + Snippet::source(&input) + .fold(true) + .origin("src/format.rs") + .annotation( + Level::Warning + .span(span) + .label("expected `Option` because of return type"), + ), + ); + + let renderer = Renderer::plain(); + let rendered = renderer.render(message).to_string(); + rendered + }); +} + +fn main() { + divan::main(); +} diff --git a/benches/simple.rs b/benches/simple.rs deleted file mode 100644 index 723793e..0000000 --- a/benches/simple.rs +++ /dev/null @@ -1,58 +0,0 @@ -#![allow(clippy::unit_arg)] -#[macro_use] -extern crate criterion; - -use criterion::{black_box, Criterion}; - -use annotate_snippets::{Level, Renderer, Snippet}; - -fn create_snippet(renderer: Renderer) { - let source = r#") -> Option { - for ann in annotations { - match (ann.range.0, ann.range.1) { - (None, None) => continue, - (Some(start), Some(end)) if start > end_index => continue, - (Some(start), Some(end)) if start >= start_index => { - let label = if let Some(ref label) = ann.label { - format!(" {}", label) - } else { - String::from("") - }; - - return Some(format!( - "{}{}{}", - " ".repeat(start - start_index), - "^".repeat(end - start), - label - )); - } - _ => continue, - } - }"#; - let message = Level::Error.title("mismatched types").id("E0308").snippet( - Snippet::source(source) - .line_start(51) - .origin("src/format.rs") - .annotation( - Level::Warning - .span(5..19) - .label("expected `Option` because of return type"), - ) - .annotation( - Level::Error - .span(26..724) - .label("expected enum `std::option::Option`"), - ), - ); - - let _result = renderer.render(message).to_string(); -} - -pub fn criterion_benchmark(c: &mut Criterion) { - c.bench_function("format", |b| { - b.iter(|| black_box(create_snippet(Renderer::plain()))); - }); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); diff --git a/src/renderer/display_list.rs b/src/renderer/display_list.rs index eea4971..fedf268 100644 --- a/src/renderer/display_list.rs +++ b/src/renderer/display_list.rs @@ -1181,7 +1181,7 @@ fn fold_prefix_suffix(mut snippet: snippet::Snippet<'_>) -> snippet::Snippet<'_> if let Some(before_new_start) = snippet.source[0..ann_start].rfind('\n') { let new_start = before_new_start + 1; - let line_offset = snippet.source[..new_start].lines().count(); + let line_offset = newline_count(&snippet.source[..new_start]); snippet.line_start += line_offset; snippet.source = &snippet.source[new_start..]; @@ -1207,6 +1207,17 @@ fn fold_prefix_suffix(mut snippet: snippet::Snippet<'_>) -> snippet::Snippet<'_> snippet } +fn newline_count(body: &str) -> usize { + #[cfg(feature = "simd")] + { + memchr::memchr_iter(b'\n', body.as_bytes()).count() + } + #[cfg(not(feature = "simd"))] + { + body.lines().count() + } +} + fn fold_body(body: Vec>) -> Vec> { const INNER_CONTEXT: usize = 1; const INNER_UNFOLD_SIZE: usize = INNER_CONTEXT * 2 + 1;