Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_text/src/unicode/lookup.rs

1.9 KiB, 25 runs

created by r1870400018:13902, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! Lookup of a character property in a generated partition table.
2//!
3//! Each table is a partition of the code point space: a sorted array of the code point at which
4//! each run begins, and a parallel array of the value that run takes. Every table begins at
5//! U+0000, so a binary search of the starts always lands, and the lookup never has a failing path.
6//!
7//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
8//! Anthropic Claude
9
10use oxedyne_fe2o3_core::prelude::*;
11
12/// A character property held in a generated partition table.
13pub trait Partitioned: Copy + Sized + 'static {
14
15 // The generated tables cover the whole code point space, so this value is
16 // never taken; it is here only to keep the lookup total.
17 const DEFAULT: Self;
18
19 /// The run starts and run values of the property.
20 fn table() -> (&'static [u32], &'static [Self]);
21
22 fn of(c: char) -> Self {
23 let (starts, vals) = Self::table();
24 match vals.get(run(starts, c)) {
25 Some(v) => *v,
26 None => Self::DEFAULT,
27 }
28 }
29}
30
31pub fn run(starts: &[u32], c: char) -> usize {
32 starts.partition_point(|s| *s <= (c as u32)).saturating_sub(1)
33}
34
35/// Zero where the table does not reach `c`.
36pub fn flags(starts: &[u32], vals: &[u8], c: char) -> u8 {
37 match vals.get(run(starts, c)) {
38 Some(v) => *v,
39 None => 0,
40 }
41}
42
43pub fn find(keys: &[u32], c: char) -> Option<usize> {
44 match keys.binary_search(&(c as u32)) {
45 Ok(i) => Some(i),
46 Err(_) => None,
47 }
48}
49
50/// The half open slice `a..b`. A generated table cannot ask for a slice that is not there, so the
51/// empty fallback keeps the caller free of a failing path; the `tables_are_consistent` test guards
52/// the invariant.
53pub fn pool(pool: &[char], a: usize, b: usize) -> &[char] {
54 match pool.get(a..b) {
55 Some(s) => s,
56 None => &[],
57 }
58}
59
60pub fn get<T: Copy>(vals: &[T], i: usize, dflt: T) -> T {
61 match vals.get(i) {
62 Some(v) => *v,
63 None => dflt,
64 }
65}