use serde::Deserialize;
use std::{collections::HashMap, env, fs, path::Path};
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir);
let cargo_toml: CargoToml = toml::from_str(include_str!("Cargo.toml")).unwrap();
let maud = cargo_toml.dependencies.get("maud").unwrap();
let version = maud.version();
fs::write(out_dir.join("maud.txt"), version).unwrap();
let locale_files = fs::read_dir("locales")
.unwrap()
.map(|e| e.unwrap())
.collect::<Vec<_>>();
let locales = locale_files
.iter()
.map(|e| e.path().with_extension(""))
.map(|p| {
let id = p.file_name().unwrap().to_str().unwrap();
let mut chars = id.chars();
let ident = match chars.next() {
None => String::new(), Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
};
(id.to_string(), ident)
});
let locale_idents = locales
.clone()
.map(|(id, ident)| format!("\t/// `{id}`\n\t{ident},"));
let locale_displays = locales
.clone()
.map(|(id, ident)| format!("\t\t\tSelf::{ident} => \"{id}\","));
let locale_idents_list = locales.map(|(_, ident)| format!("\t\t\tSelf::{ident},"));
let locales_enum = format!(
r##"#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum LangImpl {{
/// The debug lang, `qqx`.
Qqx,
{}
}}
impl ::core::fmt::Display for LangImpl {{
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {{
write!(f, "{{}}", self.as_str())
}}
}}
impl LangImpl {{
/// Returns the ID of the lang, e.g. `"en"`.
#[inline]
pub const fn as_str(&self) -> &'static str {{
match self {{
Self::Qqx => "qqx",
{}
}}
}}
/// The list of all `LangImpl` values available to users.
#[inline]
pub const fn all() -> &'static [Self] {{
&[
{}
]
}}
}}
"##,
locale_idents.collect::<Vec<_>>().join("\n"),
locale_displays.collect::<Vec<_>>().join("\n"),
locale_idents_list.collect::<Vec<_>>().join("\n"),
);
fs::write(out_dir.join("langs.rs"), locales_enum).unwrap();
println!("cargo::rerun-if-changed=build.rs,Cargo.toml,locales");
}
#[derive(Deserialize)]
struct CargoToml {
dependencies: HashMap<String, PackageManifest>,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum PackageManifest {
Version(String),
Manifest { version: String },
}
impl PackageManifest {
const fn version(&self) -> &str {
match self {
Self::Version(version) => version.as_str(),
Self::Manifest { version } => version.as_str(),
}
}
}