use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use smol_str::SmolStr;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "typescript", derive(typescript_type_def::TypeDef))]
pub struct Features {
#[cfg_attr(
feature = "typescript",
type_def(type_of = "std::collections::HashMap<String, String>")
)]
pub classes: IndexMap<SmolStr, String>,
#[cfg_attr(
feature = "typescript",
type_def(type_of = "std::collections::HashMap<String, String>")
)]
pub prefixes: IndexMap<SmolStr, String>,
#[cfg_attr(feature = "typescript", type_def(type_of = "Vec<(String, String)>"))]
pub features: Vec<(SmolStr, String)>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub include_paths: Vec<std::path::PathBuf>,
}
impl Features {
pub fn to_fea(&self) -> String {
let mut fea = String::new();
for (name, glyphs) in &self.classes {
fea.push_str(&format!("@{} = [{}];\n", name, glyphs));
}
for (prefix, code) in &self.prefixes {
if prefix != "anonymous" {
fea.push_str(&format!("# Prefix: {}\n", prefix));
}
fea.push_str(code);
fea.push('\n');
}
for (name, code) in &self.features {
fea.push_str(&format!("feature {} {{\n{}\n}} {};\n", name, code, name));
}
fea
}
pub fn from_fea(fea: &str) -> Features {
let mut features = Features::default();
features
.prefixes
.insert("anonymous".into(), fea.to_string());
features
}
}