use std::collections::HashSet;
use lightningcss::printer::PseudoClasses;
use lightningcss::stylesheet::ParserFlags;
use lightningcss::targets::{Features, Targets};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct LightningOptions {
pub include: u32,
pub exclude: u32,
pub custom_media: bool,
pub deep_selector_combinator: bool,
pub pseudo_classes: [Option<String>; 5],
pub unused_symbols: Vec<String>,
}
impl LightningOptions {
pub fn from_json(v: &serde_json::Value) -> LightningOptions {
let flag = |obj: &str, key: &str| {
v.get(obj)
.and_then(|o| o.get(key))
.and_then(|b| b.as_bool())
.unwrap_or(false)
};
let bits = |key: &str| v.get(key).and_then(|n| n.as_u64()).unwrap_or(0) as u32;
let pseudo = |key: &str| {
v.get("pseudoClasses")
.and_then(|p| p.get(key))
.and_then(|s| s.as_str())
.map(str::to_string)
};
LightningOptions {
include: bits("include"),
exclude: bits("exclude"),
custom_media: flag("drafts", "customMedia"),
deep_selector_combinator: flag("nonStandard", "deepSelectorCombinator"),
pseudo_classes: ["hover", "active", "focus", "focusVisible", "focusWithin"].map(pseudo),
unused_symbols: v
.get("unusedSymbols")
.and_then(|a| a.as_array())
.map(|a| {
a.iter()
.filter_map(|s| s.as_str().map(str::to_string))
.collect()
})
.unwrap_or_default(),
}
}
pub(crate) fn parser_flags(&self) -> ParserFlags {
let mut flags = ParserFlags::empty();
flags.set(ParserFlags::CUSTOM_MEDIA, self.custom_media);
flags.set(
ParserFlags::DEEP_SELECTOR_COMBINATOR,
self.deep_selector_combinator,
);
flags
}
pub(crate) fn targets(&self, mut targets: Targets) -> Targets {
targets.include = Features::from_bits_truncate(self.include);
targets.exclude = Features::from_bits_truncate(self.exclude);
targets
}
pub(crate) fn pseudo_classes(&self) -> Option<PseudoClasses<'_>> {
let [hover, active, focus, focus_visible, focus_within] =
self.pseudo_classes.each_ref().map(|p| p.as_deref());
self.pseudo_classes
.iter()
.any(Option::is_some)
.then_some(PseudoClasses {
hover,
active,
focus,
focus_visible,
focus_within,
})
}
pub(crate) fn unused_symbols(&self) -> HashSet<String> {
self.unused_symbols.iter().cloned().collect()
}
}