unicode-writing-script 0.2.0

The package provides detection of writing scripts from Unicode codepoints.
Documentation
#![feature(test)]

extern crate test;

use serde::Deserialize;
use unicode_writing_script::Context;

macro_rules! ok(($result:expr) => ($result.unwrap()));

#[derive(Deserialize)]
#[serde(untagged)]
enum Range {
    Single(u32),
    Double(u32, u32),
}

impl From<Range> for [u32; 2] {
    fn from(range: Range) -> Self {
        match range {
            Range::Single(value) => [value, value],
            Range::Double(start, end) => [start, end],
        }
    }
}

const CODEPOINTS: &str = "[0, 13, [32, 126], [160, 383], 399, 402, 413, [416, 417], [431, 432], [486, 487], [490, 491], [506, 511], [536, 539], [562, 563], 567, 601, 626, 688, [699, 700], [710, 711], 713, 715, [728, 733], [768, 772], [774, 780], 783, 785, 803, [806, 808], 814, 817, [884, 885], 894, [900, 906], 908, [910, 929], [931, 974], 983, [1024, 1119], [1138, 1141], [1162, 1279], [1296, 1299], [1308, 1309], [1316, 1319], [1326, 1327], [7682, 7683], [7690, 7691], [7710, 7711], [7714, 7715], [7766, 7767], [7776, 7777], [7786, 7787], [7808, 7813], 7838, [7840, 7929], [8192, 8202], [8211, 8213], [8216, 8222], [8224, 8226], 8230, 8240, [8242, 8243], [8249, 8250], [8253, 8254], 8260, 8304, [8308, 8313], [8317, 8329], [8333, 8334], 8353, [8355, 8356], [8358, 8364], 8372, [8376, 8378], [8380, 8381], 8467, [8470, 8471], 8480, 8482, 8486, 8494, [8531, 8532], [8539, 8542], [8592, 8595], 8706, 8710, 8719, [8721, 8722], 8725, [8729, 8730], 8734, 8747, 8776, 8800, [8804, 8805], [8882, 8883], 8901, 8984, 9632, 9650, 9654, 9660, 9664, 9674, 9679, 9733, [9744, 9745], 9830, 10003, 11800, [57348, 57349], [62522, 62523], [62560, 62579], [62616, 62623], [62662, 62663], [62668, 62669], [62674, 62679], [62730, 62731], [62734, 62771], [62774, 62777], [62780, 62783], 63031, 63171, 63197, [63199, 63219], 63743, [64256, 64260]]";

#[bench]
fn detect(bencher: &mut test::Bencher) {
    let codepoints: Vec<Range> = ok!(serde_json::from_str(CODEPOINTS));
    let codepoints = codepoints.into_iter().map(Into::into).collect::<Vec<_>>();
    let context = Context::default();
    bencher.iter(|| test::black_box(context.detect(codepoints.iter().cloned())));
}