use crate::data::CHAR_BLOCKS;
use std::convert::{identity, TryFrom};
#[cfg(feature = "compat")]
mod compat;
mod data;
mod pinyin;
#[cfg(feature = "heteronym")]
mod pinyin_multi;
#[cfg(feature = "compat")]
pub use crate::compat::*;
pub use crate::pinyin::{Pinyin, PinyinStrIter, ToPinyin};
#[cfg(feature = "heteronym")]
pub use crate::pinyin_multi::{PinyinMulti, PinyinMultiIter, PinyinMultiStrIter, ToPinyinMulti};
pub fn to_pinyin_vec<F>(input: &str, f: F) -> Vec<&'static str>
where
F: Fn(Pinyin) -> &'static str,
{
input.to_pinyin().filter_map(identity).map(f).collect()
}
struct PinyinData {
#[cfg(feature = "plain")]
plain: &'static str,
#[cfg(feature = "with_tone")]
with_tone: &'static str,
#[cfg(feature = "with_tone_num")]
with_tone_num: &'static str,
#[cfg(feature = "with_tone_num_end")]
with_tone_num_end: &'static str,
#[cfg(feature = "compat")]
split: usize,
}
struct CharBlock {
start_code: u32,
data: &'static [u16],
#[cfg(feature = "heteronym")]
heteronym: &'static [u16],
}
#[inline]
fn get_block_and_index(ch: char) -> Option<(&'static CharBlock, usize)> {
let code = u32::from(ch);
for block in CHAR_BLOCKS.iter() {
if code < block.start_code {
return None;
}
let idx = usize::try_from(code - block.start_code).unwrap();
if idx < block.data.len() {
return Some((block, idx));
}
}
None
}