1use crate::{Decode, Encode};
2
3pub struct Table<'a> {
5 pub bits: u32,
7 pub fini: &'a [char],
9 pub init: &'a [char],
11 decode: [&'a [(u16, u16)]; 17],
12}
13
14impl<'a> Table<'a> {
15 pub(crate) fn decode(&self, ch: char) -> Option<(u32, bool)> {
16 let plane = self.decode[ch as usize >> 16];
17 let idx = plane.binary_search_by_key(&(ch as u16), |&x| x.0);
18 let code = plane[idx.ok()?].1 as u32;
19 Some((code & ((1 << 15) - 1), code >> 15 != 0))
20 }
21
22 pub fn encode_iter<I>(&'a self, iter: I) -> Encode<'a, I::IntoIter>
24 where
25 I: IntoIterator<Item = u8>,
26 {
27 Encode::new(self, iter.into_iter())
28 }
29
30 pub fn decode_iter<I>(&'a self, iter: I) -> Decode<'a, I::IntoIter>
34 where
35 I: IntoIterator<Item = char>,
36 {
37 Decode::new(self, iter.into_iter())
38 }
39}
40
41#[cfg(any(feature = "std", test))]
42impl Table<'_> {
43 pub fn encode_str<I>(&self, iter: I) -> String
45 where
46 I: IntoIterator<Item = u8>,
47 {
48 self.encode_iter(iter).collect()
49 }
50
51 pub fn decode_vec<I>(&self, iter: I) -> Result<Vec<u8>, char>
55 where
56 I: IntoIterator<Item = char>,
57 {
58 self.decode_iter(iter).collect()
59 }
60}
61
62#[cfg(test)]
63impl Table<'_> {
64 pub(crate) fn with<T>(bits: u32, f: impl FnOnce(&Table) -> T) -> T {
65 let fin_len = if bits > 8 { 1 << (bits - 8) } else { 0 };
66 let chs: Vec<_> = ('\0'..).take(fin_len + (1 << bits)).collect();
67 let mut decode = std::iter::zip(
68 chs.iter().map(|&c| c as u16),
69 (0..fin_len as u16).map(|x| x | (1 << 15)).chain(0..),
70 );
71 let decode = std::array::from_fn(|_| decode.by_ref().take(65536).collect());
72 f(&Table {
73 bits,
74 fini: &chs[..fin_len],
75 init: &chs[fin_len..],
76 decode: decode.each_ref().map(|a: &Vec<_>| &**a),
77 })
78 }
79}
80
81#[allow(warnings)]
83pub mod tables {
84 use super::*;
85 include!(concat!(env!("OUT_DIR"), "/table.rs"));
86}