mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-04 03:00:03 +00:00
Leon template library (#766)
* leon: first implementation * Update crates/leon/src/values.rs Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Workaround orphan rules to make API more intuitive * Fmt * Clippy * Use CoW * Use cow for items too * Test that const construction works * leon: Initial attempt at O(n) parser * leon: finish parser (except escapes) * leon: Improve ergonomics of compile-time templates * Document helpers * leon: Docs tweaks * leon: Use macro to minimise parser tests * leon: add escapes to parser * leon: test escapes preceding keys * leon: add multibyte tests * leon: test escapes following keys * Format * Debug * leon: Don't actually need to keep track of the key * leon: Parse to vec first * leon: there's actually no need for string cows * leon: reorganise and redo macro now that there's no coww * Well that was silly * leon: Adjust text end when pushing * leon: catch unbalanced keys * Add error tests * leon: Catch unfinished escape * Comment out debugging * leon: fuzz * Clippy * leon: Box parse error * leon: &dyn instead of impl * Can't impl FromStr, so rename to parse * Add Vec<> to values * leon: Add benches for ways to supply values * leon: Add bench comparing to std and tt * Fix fuzz * Fmt * Split ParseError and RenderError * Make miette optional * Remove RenderError lifetime * Simplify ParseError type schema * Write concrete Values types instead of generics * Add license files * Reduce criterion deps * Make default a cow * Add a CLI leon tool * Fix tests * Clippy * Disable cli by default * Avoid failing the build when cli is off * Add to ci * Update crates/leon/src/main.rs Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Update crates/leon/Cargo.toml Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Bump version * Error not transparent * Diagnostic can do forwarding * Simplify error type * Expand doc examples * Generic Values for Hash and BTree maps * One more borrowed * Forward implementations * More generics * Add has_keys * Lock stdout in leon tool * No more debug comments in parser * Even more generics * Macros to reduce bench duplication * Further simplify error * Fix leon main * Stable support * Clippy --------- Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
daf8cdd010
commit
2227d363f7
20 changed files with 2382 additions and 162 deletions
298
crates/leon/benches/values.rs
Normal file
298
crates/leon/benches/values.rs
Normal file
|
@ -0,0 +1,298 @@
|
|||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use leon::{vals, Template, Values, ValuesFn};
|
||||
|
||||
macro_rules! make_values {
|
||||
($($name:expr => $value:expr),*) => {
|
||||
(
|
||||
&[$(($name, $value)),*],
|
||||
{
|
||||
let mut map = HashMap::new();
|
||||
$(
|
||||
map.insert($name, $value);
|
||||
)*
|
||||
map
|
||||
},
|
||||
vals(|key| match key {
|
||||
$(
|
||||
$name => Some(Cow::Borrowed($value)),
|
||||
)*
|
||||
_ => None,
|
||||
})
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
fn one_replace(c: &mut Criterion) {
|
||||
const TEMPLATE: &str = "Hello, {name}!";
|
||||
|
||||
let (slice, hashmap, vals) = make_values!(
|
||||
"name" => "marcus"
|
||||
);
|
||||
|
||||
inner_bench("one replace", c, TEMPLATE, vals, hashmap, slice);
|
||||
}
|
||||
|
||||
fn some_replaces(c: &mut Criterion) {
|
||||
const TEMPLATE: &str = "hello {name}! i am {age} years old. my goal is to {goal}. i like: {flower}, {music}, {animal}, {color}, {food}. i'm drinking {drink}";
|
||||
|
||||
let (slice, hashmap, vals) = make_values!(
|
||||
"name" => "marcus",
|
||||
"age" => "42",
|
||||
"goal" => "primary",
|
||||
"flower" => "lotus",
|
||||
"music" => "jazz",
|
||||
"animal" => "cat",
|
||||
"color" => "blue",
|
||||
"food" => "pizza",
|
||||
"drink" => "coffee"
|
||||
);
|
||||
|
||||
inner_bench("some replaces", c, TEMPLATE, vals, hashmap, slice);
|
||||
}
|
||||
|
||||
fn many_replaces(c: &mut Criterion) {
|
||||
const TEMPLATE: &str = "
|
||||
{artichoke}
|
||||
{aubergine}
|
||||
{asparagus}
|
||||
{broccoflower}
|
||||
{broccoli}
|
||||
{brussels sprouts}
|
||||
{cabbage}
|
||||
{kohlrabi}
|
||||
{Savoy cabbage}
|
||||
{red cabbage}
|
||||
{cauliflower}
|
||||
{celery}
|
||||
{endive}
|
||||
{fiddleheads}
|
||||
{frisee}
|
||||
{fennel}
|
||||
{greens}
|
||||
{arugula}
|
||||
{bok choy}
|
||||
{chard}
|
||||
{collard greens}
|
||||
{kale}
|
||||
{lettuce}
|
||||
{mustard greens}
|
||||
{spinach}
|
||||
{herbs}
|
||||
{anise}
|
||||
{basil}
|
||||
{caraway}
|
||||
{coriander}
|
||||
{chamomile}
|
||||
{daikon}
|
||||
{dill}
|
||||
{squash}
|
||||
{lavender}
|
||||
{cymbopogon}
|
||||
{marjoram}
|
||||
{oregano}
|
||||
{parsley}
|
||||
{rosemary}
|
||||
{thyme}
|
||||
{legumes}
|
||||
{alfalfa sprouts}
|
||||
{azuki beans}
|
||||
{bean sprouts}
|
||||
{black beans}
|
||||
{black-eyed peas}
|
||||
{borlotti bean}
|
||||
{broad beans}
|
||||
{chickpeas, garbanzos, or ceci beans}
|
||||
{green beans}
|
||||
{kidney beans}
|
||||
{lentils}
|
||||
{lima beans or butter bean}
|
||||
{mung beans}
|
||||
{navy beans}
|
||||
{peanuts}
|
||||
{pinto beans}
|
||||
{runner beans}
|
||||
{split peas}
|
||||
{soy beans}
|
||||
{peas}
|
||||
{mange tout or snap peas}
|
||||
{mushrooms}
|
||||
{nettles}
|
||||
{New Zealand spinach}
|
||||
{okra}
|
||||
{onions}
|
||||
{chives}
|
||||
{garlic}
|
||||
{leek}
|
||||
{onion}
|
||||
{shallot}
|
||||
{scallion}
|
||||
{peppers}
|
||||
{bell pepper}
|
||||
{chili pepper}
|
||||
{jalapeño}
|
||||
{habanero}
|
||||
{paprika}
|
||||
{tabasco pepper}
|
||||
{cayenne pepper}
|
||||
{radicchio}
|
||||
{rhubarb}
|
||||
{root vegetables}
|
||||
{beetroot}
|
||||
{beet}
|
||||
{mangelwurzel}
|
||||
{carrot}
|
||||
{celeriac}
|
||||
{corms}
|
||||
{eddoe}
|
||||
{konjac}
|
||||
{taro}
|
||||
{water chestnut}
|
||||
{ginger}
|
||||
{parsnip}
|
||||
{rutabaga}
|
||||
{radish}
|
||||
{wasabi}
|
||||
";
|
||||
|
||||
let (slice, hashmap, vals) = make_values!(
|
||||
"artichoke" => "Abiu",
|
||||
"aubergine" => "Açaí",
|
||||
"asparagus" => "Acerola",
|
||||
"broccoflower" => "Akebi",
|
||||
"broccoli" => "Ackee",
|
||||
"brussels sprouts" => "African Cherry Orange",
|
||||
"cabbage" => "American Mayapple",
|
||||
"kohlrabi" => "Apple",
|
||||
"Savoy cabbage" => "Apricot",
|
||||
"red cabbage" => "Araza",
|
||||
"cauliflower" => "Avocado",
|
||||
"celery" => "Banana",
|
||||
"endive" => "Bilberry",
|
||||
"fiddleheads" => "Blackberry",
|
||||
"frisee" => "Blackcurrant",
|
||||
"fennel" => "Black sapote",
|
||||
"greens" => "Blueberry",
|
||||
"arugula" => "Boysenberry",
|
||||
"bok choy" => "Breadfruit",
|
||||
"chard" => "Buddha's hand",
|
||||
"collard greens" => "Cactus pear",
|
||||
"kale" => "Canistel",
|
||||
"lettuce" => "Cashew",
|
||||
"mustard greens" => "Cempedak",
|
||||
"spinach" => "Cherimoya",
|
||||
"herbs" => "Cherry",
|
||||
"anise" => "Chico fruit",
|
||||
"basil" => "Cloudberry",
|
||||
"caraway" => "Coco de mer",
|
||||
"coriander" => "Coconut",
|
||||
"chamomile" => "Crab apple",
|
||||
"daikon" => "Cranberry",
|
||||
"dill" => "Currant",
|
||||
"squash" => "Damson",
|
||||
"lavender" => "Date",
|
||||
"cymbopogon" => "Dragonfruit",
|
||||
"marjoram" => "Pitaya",
|
||||
"oregano" => "Durian",
|
||||
"parsley" => "Elderberry",
|
||||
"rosemary" => "Feijoa",
|
||||
"thyme" => "Fig",
|
||||
"legumes" => "Finger Lime",
|
||||
"alfalfa sprouts" => "Caviar Lime",
|
||||
"azuki beans" => "Goji berry",
|
||||
"bean sprouts" => "Gooseberry",
|
||||
"black beans" => "Grape",
|
||||
"black-eyed peas" => "Raisin",
|
||||
"borlotti bean" => "Grapefruit",
|
||||
"broad beans" => "Grewia asiatica",
|
||||
"chickpeas, garbanzos, or ceci beans" => "Guava",
|
||||
"green beans" => "Hala Fruit",
|
||||
"kidney beans" => "Honeyberry",
|
||||
"lentils" => "Huckleberry",
|
||||
"lima beans or butter bean" => "Jabuticaba",
|
||||
"mung beans" => "Jackfruit",
|
||||
"navy beans" => "Jambul",
|
||||
"peanuts" => "Japanese plum",
|
||||
"pinto beans" => "Jostaberry",
|
||||
"runner beans" => "Jujube",
|
||||
"split peas" => "Juniper berry",
|
||||
"soy beans" => "Kaffir Lime",
|
||||
"peas" => "Kiwano",
|
||||
"mange tout or snap peas" => "Kiwifruit",
|
||||
"mushrooms" => "Kumquat",
|
||||
"nettles" => "Lemon",
|
||||
"New Zealand spinach" => "Lime",
|
||||
"okra" => "Loganberry",
|
||||
"onions" => "Longan",
|
||||
"chives" => "Loquat",
|
||||
"garlic" => "Lulo",
|
||||
"leek" => "Lychee",
|
||||
"onion" => "Magellan Barberry",
|
||||
"shallot" => "Mamey Apple",
|
||||
"scallion" => "Mamey Sapote",
|
||||
"peppers" => "Mango",
|
||||
"bell pepper" => "Mangosteen",
|
||||
"chili pepper" => "Marionberry",
|
||||
"jalapeño" => "Melon",
|
||||
"habanero" => "Cantaloupe",
|
||||
"paprika" => "Galia melon",
|
||||
"tabasco pepper" => "Honeydew",
|
||||
"cayenne pepper" => "Mouse melon",
|
||||
"radicchio" => "Musk melon",
|
||||
"rhubarb" => "Watermelon",
|
||||
"root vegetables" => "Miracle fruit",
|
||||
"beetroot" => "Momordica fruit",
|
||||
"beet" => "Monstera deliciosa",
|
||||
"mangelwurzel" => "Mulberry",
|
||||
"carrot" => "Nance",
|
||||
"celeriac" => "Nectarine",
|
||||
"corms" => "Orange",
|
||||
"eddoe" => "Blood orange",
|
||||
"konjac" => "Clementine",
|
||||
"taro" => "Mandarine",
|
||||
"water chestnut" => "Tangerine",
|
||||
"ginger" => "Papaya",
|
||||
"parsnip" => "Passionfruit",
|
||||
"rutabaga" => "Pawpaw",
|
||||
"radish" => "Peach",
|
||||
"wasabi" => "Pear"
|
||||
);
|
||||
|
||||
inner_bench("many replaces", c, TEMPLATE, vals, hashmap, slice);
|
||||
}
|
||||
|
||||
fn inner_bench<F>(
|
||||
name: &str,
|
||||
c: &mut Criterion,
|
||||
template_str: &str,
|
||||
vals: ValuesFn<F>,
|
||||
hashmap: HashMap<&str, &str>,
|
||||
slice: &[(&str, &str)],
|
||||
) where
|
||||
F: for<'s> Fn(&'s str) -> Option<Cow<'s, str>> + Send + 'static,
|
||||
{
|
||||
c.bench_function(&format!("{name}, fn"), |b| {
|
||||
b.iter(|| {
|
||||
let template = Template::parse(black_box(template_str)).unwrap();
|
||||
black_box(template.render(&vals).unwrap());
|
||||
})
|
||||
});
|
||||
c.bench_function(&format!("{name}, hashmap"), |b| {
|
||||
b.iter(|| {
|
||||
let template = Template::parse(black_box(template_str)).unwrap();
|
||||
black_box(template.render(&hashmap).unwrap());
|
||||
})
|
||||
});
|
||||
c.bench_function(&format!("{name}, slice"), |b| {
|
||||
b.iter(|| {
|
||||
let template = Template::parse(black_box(template_str)).unwrap();
|
||||
black_box(template.render(&slice as &dyn Values).unwrap());
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(one, one_replace);
|
||||
criterion_group!(some, some_replaces);
|
||||
criterion_group!(many, many_replaces);
|
||||
criterion_main!(one, some, many);
|
Loading…
Add table
Add a link
Reference in a new issue