use std::collections::HashSet;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use icu_properties::props::GeneralCategory;
use icu_properties::{
props::{Dash, QuotationMark},
CodePointMapData, CodePointSetData,
};
use phf_codegen::Map as PhfMap;
const QUOTE_DOUBLE_OVERRIDES: &[char] = &[
'\u{00AB}', '\u{00BB}', '\u{02BA}', '\u{02EE}', '\u{201C}', '\u{201D}', '\u{201E}', '\u{201F}', '\u{2033}', '\u{2036}', '\u{275D}', '\u{275E}', '\u{2760}', '\u{276E}', '\u{276F}', '\u{1F676}', '\u{1F677}', '\u{1F678}', '\u{2E42}', '\u{301D}', '\u{301E}', '\u{301F}', ];
const DOUBLE_QUOTE_REPLACEMENT: &str = "'\"'";
const SINGLE_QUOTE_REPLACEMENT: &str = "'\\''";
const QUOTE_SINGLE_OVERRIDES: &[char] = &[
'\u{0149}', '\u{02B9}', '\u{02BC}', '\u{055A}', '\u{07F4}', '\u{07F5}', '\u{2018}', '\u{2019}', '\u{201A}', '\u{201B}', '\u{2032}', '\u{2034}', '\u{2035}', '\u{2037}', '\u{2039}', '\u{203A}', '\u{2057}', '\u{275B}', '\u{275C}', '\u{275F}', '\u{FF07}', '\u{E0027}', ];
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
let dest_path = out_dir.join("generated_tables.rs");
let mut file = File::create(&dest_path).expect("failed to create generated tables");
let mut space_map = PhfMap::<char>::new();
let mut dash_map = PhfMap::<char>::new();
let mut quote_map = PhfMap::<char>::new();
for range in CodePointMapData::<GeneralCategory>::new()
.iter_ranges_for_value(GeneralCategory::SpaceSeparator)
{
for codepoint in range {
let ch = char::from_u32(codepoint).expect("valid code point");
if ch != ' ' {
space_map.entry(ch, "' '");
}
}
}
for range in CodePointSetData::new::<Dash>().iter_ranges() {
for codepoint in range {
let ch = char::from_u32(codepoint).expect("valid code point");
if ch != '-' {
dash_map.entry(ch, "'-'");
}
}
}
let mut seen_quotes = HashSet::new();
for range in CodePointSetData::new::<QuotationMark>().iter_ranges() {
for codepoint in range {
let ch = char::from_u32(codepoint).expect("valid code point");
if ch == '\'' || ch == '"' {
continue;
}
let mapped = if QUOTE_DOUBLE_OVERRIDES.contains(&ch) {
DOUBLE_QUOTE_REPLACEMENT
} else {
SINGLE_QUOTE_REPLACEMENT
};
if seen_quotes.insert(ch) {
quote_map.entry(ch, mapped);
}
}
}
for &ch in QUOTE_SINGLE_OVERRIDES {
if ch == '\'' || ch == '"' {
continue;
}
if seen_quotes.insert(ch) {
quote_map.entry(ch, SINGLE_QUOTE_REPLACEMENT);
}
}
for &ch in QUOTE_DOUBLE_OVERRIDES {
if ch == '\'' || ch == '"' {
continue;
}
if seen_quotes.insert(ch) {
quote_map.entry(ch, DOUBLE_QUOTE_REPLACEMENT);
}
}
writeln!(file, "// AUTO-GENERATED FILE, DO NOT EDIT\n").unwrap();
write_map(&mut file, "SPACE_MAP", &space_map);
write_map(&mut file, "DASH_MAP", &dash_map);
write_map(&mut file, "QUOTE_MAP", "e_map);
}
fn write_map(file: &mut File, name: &str, map: &PhfMap<char>) {
let display = map.build().to_string();
writeln!(
file,
"pub static {name}: ::phf::Map<char, char> = {display};\n"
)
.unwrap();
}