use std::hint::black_box;
use criterion::Criterion;
use neure::prelude::*;
#[derive(Debug, PartialEq)]
pub struct Color {
pub red: u8,
pub green: u8,
pub blue: u8,
}
fn bench_color(c: &mut Criterion) {
let color_str = "#2F14DF";
c.bench_function("color of nom", {
move |b| {
b.iter(|| {
color_nom::parse(black_box(color_str));
black_box(())
})
}
});
c.bench_function("color of neure", {
move |b| {
b.iter(|| {
color_neure::parse(black_box(color_str));
black_box(())
})
}
});
}
criterion::criterion_group!(
name = benches;
config = Criterion::default().configure_from_args();
targets = bench_color
);
criterion::criterion_main!(benches);
mod color_nom {
use super::*;
use nom::{
IResult, Parser,
bytes::complete::{tag, take_while_m_n},
combinator::map_res,
};
fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
u8::from_str_radix(input, 16)
}
fn is_hex_digit(c: char) -> bool {
('0'..':').contains(&c) || ('A'..'G').contains(&c)
}
fn hex_primary(input: &str) -> IResult<&str, u8> {
map_res(take_while_m_n(2, 2, is_hex_digit), from_hex).parse(input)
}
fn hex_color(input: &str) -> IResult<&str, Color> {
let (input, _) = tag("#")(input)?;
let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?;
Ok((input, Color { red, green, blue }))
}
pub fn parse(str: &str) {
let (_, color) = hex_color(str).unwrap();
assert_eq!(
color,
Color {
red: 47,
green: 20,
blue: 223,
}
);
}
}
mod color_neure {
use super::*;
fn is_hex_digit(c: &char) -> bool {
('0'..':').contains(c) || ('A'..'G').contains(c)
}
fn parser(str: &str) -> Result<Color, neure::err::Error> {
let hex = is_hex_digit.count::<2>(); let hex = hex.try_map(map::from_str_radix::<u8>(16));
let parser = hex
.then(hex.then(hex))
.map(|(red, (green, blue))| Color { red, green, blue });
let parser = parser.prefix("#");
RegexCtx::new(str).ctor(&parser)
}
pub fn parse(str: &str) {
let color = parser(str).unwrap();
assert_eq!(
color,
Color {
red: 47,
green: 20,
blue: 223,
}
);
}
}