use itertools;
use lazy_static::lazy_static;
use crate::converter::{ZhConverter, ZhConverterBuilder};
use crate::Variant;
pub const ZH_HANT_TABLE: (&str, &str) = (
include_str!(concat!(env!("OUT_DIR"), "/zh2Hant.from.conv")),
include_str!(concat!(env!("OUT_DIR"), "/zh2Hant.to.conv")),
);
pub const ZH_HANS_TABLE: (&str, &str) = (
include_str!(concat!(env!("OUT_DIR"), "/zh2Hans.from.conv")),
include_str!(concat!(env!("OUT_DIR"), "/zh2Hans.to.conv")),
);
pub const ZH_TW_TABLE: (&str, &str) = (
include_str!(concat!(env!("OUT_DIR"), "/zh2TW.from.conv")),
include_str!(concat!(env!("OUT_DIR"), "/zh2TW.to.conv")),
);
pub const ZH_HK_TABLE: (&str, &str) = (
include_str!(concat!(env!("OUT_DIR"), "/zh2HK.from.conv")),
include_str!(concat!(env!("OUT_DIR"), "/zh2HK.to.conv")),
);
pub const ZH_MO_TABLE: (&str, &str) = ZH_HK_TABLE;
pub const ZH_CN_TABLE: (&str, &str) = (
include_str!(concat!(env!("OUT_DIR"), "/zh2CN.from.conv")),
include_str!(concat!(env!("OUT_DIR"), "/zh2CN.to.conv")),
);
pub const ZH_SG_TABLE: (&str, &str) = ZH_CN_TABLE;
pub const ZH_MY_TABLE: (&str, &str) = ZH_SG_TABLE;
lazy_static! {
pub static ref ZH_HANT_TW_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_TW_TABLE, ZH_HANT_TABLE);
pub static ref ZH_HANT_HK_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_HK_TABLE, ZH_HANT_TABLE);
pub static ref ZH_HANT_MO_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_MO_TABLE, ZH_HANT_TABLE);
pub static ref ZH_HANS_CN_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_CN_TABLE, ZH_HANS_TABLE);
pub static ref ZH_HANS_SG_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_SG_TABLE, ZH_HANS_TABLE);
pub static ref ZH_HANS_MY_TABLE: (&'static str, &'static str) =
merge_tables_leaked(ZH_MY_TABLE, ZH_HANS_TABLE);
}
fn merge_tables_leaked(conv1: (&str, &str), conv2: (&str, &str)) -> (&'static str, &'static str) {
let (froms, tos) = merge_tables(conv1, conv2);
(
Box::leak(froms.into_boxed_str()),
Box::leak(tos.into_boxed_str()),
)
}
pub fn merge_tables(conv1: (&str, &str), conv2: (&str, &str)) -> (String, String) {
let mut froms = String::with_capacity(conv1.0.len() + conv2.0.len());
let mut tos = String::with_capacity(conv1.1.len() + conv2.1.len());
let mut it = itertools::Itertools::merge_by(
itertools::zip(conv1.0.trim().split('|'), conv1.1.trim().split('|')),
itertools::zip(conv2.0.trim().split('|'), conv2.1.trim().split('|')),
|pair1, pair2| pair1.0.len() >= pair2.0.len(),
)
.peekable();
while let Some((from, to)) = it.next() {
froms.push_str(from);
tos.push_str(to);
if it.peek().is_some() {
froms.push('|');
tos.push('|');
}
}
(froms, tos)
}
pub fn build_converter(variant: Variant, table: (&str, &str)) -> ZhConverter {
ZhConverterBuilder::new()
.target(variant)
.table(table)
.dfa(true)
.build()
}