unocss_classes_utils/
lib.rs

1use once_cell::sync::Lazy;
2use regex_lite::{Captures, Regex};
3
4static CLASS_GROUP_REG: Lazy<Regex> = Lazy::new(|| {
5    Regex::new(
6        r"(?m)((?:[!@<~\w+:_/-]|\[&?>?:?\S*\])+?)(-|:)\(((?:[~!<>\w\s:/\\,%#.$?-]|\[.*?\])+?)\)",
7    )
8    .unwrap()
9});
10static WHITESPACE_REG: Lazy<Regex> = Lazy::new(|| Regex::new(r"\s").unwrap());
11static WHITESPACES_REG: Lazy<Regex> = Lazy::new(|| Regex::new(r"\s+").unwrap());
12static IMPORTANCE_REG: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(!?)(.*)").unwrap());
13
14const SEPARATORS: [&str; 2] = ["-", ":"];
15const DEPTH: u8 = 10;
16
17fn shallow_transform(str: &str) -> String {
18    let str = WHITESPACES_REG.replace_all(str, " ");
19
20    CLASS_GROUP_REG
21        .replace_all(str.trim(), |caps: &Captures| {
22            if !SEPARATORS.contains(&&caps[2]) {
23                return caps[0].to_string();
24            }
25
26            WHITESPACE_REG
27                .split(&caps[3])
28                .filter(|item| !item.is_empty())
29                .map(|item| {
30                    if item == "~" {
31                        caps[1].to_string()
32                    } else {
33                        IMPORTANCE_REG
34                            .replace(item, format!("${{1}}{}{}${{2}}", &caps[1], &caps[2]))
35                            .to_string()
36                    }
37                })
38                .collect::<Vec<String>>()
39                .join(" ")
40        })
41        .into_owned()
42}
43
44/// based on https://github.com/unocss/unocss/blob/main/packages/core/src/utils/variantGroup.ts
45pub fn transform_variant_groups(str: String) -> String {
46    let mut depth = DEPTH;
47    let mut previous = str;
48
49    loop {
50        let transformed = shallow_transform(&previous);
51        depth -= 1;
52
53        if transformed == previous || depth == 0 {
54            break previous;
55        }
56
57        previous = transformed;
58    }
59}