50 lines
1.3 KiB
Rust
50 lines
1.3 KiB
Rust
use u_fst::raw::{Fst, Output};
|
|
|
|
use crate::element::{Elements, Range};
|
|
use crate::weights::EXPLICIT_WEIGHTS;
|
|
|
|
const TABLE: Fst<&'static [u8]> =
|
|
Fst::new_unchecked(include_bytes!(concat!(env!("OUT_DIR"), "/table.fst")));
|
|
|
|
pub(crate) fn lookup(value: &[char]) -> Option<(Elements, usize)> {
|
|
let mut node = TABLE.root();
|
|
let mut out = Output::zero();
|
|
|
|
let mut last_match = None;
|
|
|
|
'char: for (i, &c) in value.iter().enumerate() {
|
|
for b in (c as u32).to_ne_bytes() {
|
|
if let Some(trans_index) = node.find_input(b) {
|
|
let t = node.transition(trans_index);
|
|
|
|
node = TABLE.node(t.addr);
|
|
out = out.cat(t.out);
|
|
|
|
if node.is_final() {
|
|
last_match = Some((out.cat(node.final_output()).value(), i));
|
|
}
|
|
} else {
|
|
break 'char;
|
|
}
|
|
}
|
|
}
|
|
|
|
last_match.map(|(data, idx)| {
|
|
(
|
|
if data & 0x1 == 1 {
|
|
Elements {
|
|
buf: &[],
|
|
cur: data,
|
|
}
|
|
} else {
|
|
let r = Range(data >> 1);
|
|
|
|
let (first, buf) = EXPLICIT_WEIGHTS[r.start()..r.end()].split_at(1);
|
|
|
|
Elements { buf, cur: first[0] }
|
|
},
|
|
idx,
|
|
)
|
|
})
|
|
}
|