use std::fmt::Write as _;
use std::time::{Duration, Instant};
use leaf_ffi::LeafDoc;
fn main() {
let mut args = std::env::args().skip(1);
let source = match args.next().as_deref() {
Some("--dump") => {
let path = args.next().expect("--dump takes a path");
std::fs::write(&path, generated()).unwrap_or_else(|e| panic!("{path}: {e}"));
return;
}
Some(path) => std::fs::read_to_string(path).unwrap_or_else(|e| panic!("{path}: {e}")),
None => generated(),
};
let words = source.split_whitespace().count();
let profile = if cfg!(debug_assertions) {
"dev"
} else {
"release"
};
println!(
"document: {} bytes, {words} words · profile: {profile}\n",
source.len()
);
let open = Instant::now();
let doc = LeafDoc::new(source.clone(), "markdown".into()).expect("parse");
let opened = open.elapsed();
let first = Instant::now();
let view = doc.set_unwrapped();
let first_view = first.elapsed();
let runs: usize = view.rows.iter().map(|r| r.runs.len()).sum();
println!("rows: {} · runs: {runs}", view.rows.len());
println!("{:<52} {:>10}", "open (twig parse)", fmt(opened));
println!(
"{:<52} {:>10}",
"first view (build the map + the frame)",
fmt(first_view)
);
let len = doc.doc_end_offset();
let mid = len / 2;
let mid_utf16 = doc.utf16_index_for_offset(mid);
let mid_row = doc.pos_for_offset(mid).row;
row("view() — the whole frame, unchanged", || {
std::hint::black_box(doc.view());
});
row("pos_for_offset (mid-document)", || {
std::hint::black_box(doc.pos_for_offset(mid));
});
row("utf16_index_for_offset (mid-document)", || {
doc.utf16_index_for_offset(mid);
});
row("offset_for_utf16_index (mid-document)", || {
doc.offset_for_utf16_index(mid_utf16);
});
row("text_in_range (whole document)", || {
std::hint::black_box(doc.text_in_range(0, len));
});
row("counts", || {
std::hint::black_box(doc.counts());
});
row("click_ch (place the caret)", || {
std::hint::black_box(doc.click_ch(mid_row, 3, false));
});
row("click_ch extend (grow a selection)", || {
doc.click_ch(mid_row, 0, false);
std::hint::black_box(doc.click_ch(mid_row + 4, 0, true));
});
doc.click_ch(mid_row, 3, false);
row("selection_counts (rows selected)", || {
doc.click_ch(mid_row, 0, false);
doc.click_ch(mid_row + 4, 0, true);
std::hint::black_box(doc.selection_counts());
});
doc.click_ch(mid_row, 3, false);
row("insert one character", || {
std::hint::black_box(doc.insert("x".into()));
});
row("utf16_index_for_offset (first after an edit)", || {
doc.insert("x".into());
doc.utf16_index_for_offset(mid);
});
row("newline", || {
std::hint::black_box(doc.newline());
});
let inc = LeafDoc::new(source, "markdown".into()).expect("parse");
inc.set_incremental_frames(true);
let _ = inc.set_unwrapped();
let lifted = inc.click_ch(mid_row, 3, false).rows.len();
row(
&format!("click_ch, as a change ({lifted} rows lifted)"),
|| {
std::hint::black_box(inc.click_ch(mid_row, 3, false));
},
);
let lifted = inc.insert("x".into()).rows.len();
row(
&format!("insert one character, as a change ({lifted} rows lifted)"),
|| {
std::hint::black_box(inc.insert("x".into()));
},
);
inc.click_ch(mid_row, 0, false);
let lifted = inc.click_ch(mid_row + 4, 0, true).rows.len();
row(
&format!("click_ch extend, as a change ({lifted} rows lifted)"),
|| {
inc.click_ch(mid_row, 0, false);
std::hint::black_box(inc.click_ch(mid_row + 4, 0, true));
},
);
}
fn row(label: &str, mut f: impl FnMut()) {
let mut samples: Vec<Duration> = (0..7)
.map(|_| {
let t = Instant::now();
f();
t.elapsed()
})
.collect();
samples.sort();
println!("{label:<52} {:>10}", fmt(samples[samples.len() / 2]));
}
fn fmt(d: Duration) -> String {
let us = d.as_micros();
if us >= 10_000 {
format!("{:.1} ms", us as f64 / 1000.0)
} else {
format!("{us} µs")
}
}
fn generated() -> String {
let words: Vec<&str> = "the document carries its own identity and a reference resolves \
against whatever archive holds it so that moving a file between checkouts changes \
nothing a reader can see each node names its root which is what lets a foreign \
parent stand in for a path nobody has written down yet"
.split_whitespace()
.collect();
let mut out = String::from("# A generated design document\n\n");
let mut w = 0usize;
let mut para = 0usize;
while w < 14_000 {
if para.is_multiple_of(9) {
let _ = writeln!(out, "## Section {}\n", para / 9 + 1);
}
match para % 11 {
7 => {
for i in 0..5 {
let _ = writeln!(out, "- item {i} with `code_{i}` and *emphasis* in it");
w += 8;
}
out.push('\n');
}
9 => {
out.push_str("| key | value | note |\n|---|---|---|\n");
for i in 0..4 {
let _ = writeln!(out, "| `k{i}` | value {i} | a short note |");
w += 6;
}
out.push('\n');
}
10 => {
out.push_str("```rust\nfn example() -> u32 {\n 42\n}\n```\n\n");
w += 6;
}
_ => {
let n = 40 + (para * 17) % 90;
for i in 0..n {
let word = words[(para * 7 + i * 3) % words.len()];
match (para + i) % 23 {
0 => {
let _ = write!(out, "`{word}_{i}` ");
}
5 => {
let _ = write!(out, "*{word}* ");
}
11 => {
let _ = write!(out, "[{word}](https://example.org/{para}/{i}) ");
}
17 => {
let _ = write!(out, "**{word}** ");
}
_ => {
out.push_str(word);
out.push(' ');
}
}
}
w += n;
out.push_str("\n\n");
}
}
para += 1;
}
out
}