stylex_transform/shared/structures/
pre_rule.rs1use std::fmt::Debug;
2
3use indexmap::IndexMap;
4use swc_core::ecma::ast::Expr;
5
6use crate::shared::utils::common::type_of;
7use crate::shared::utils::core::convert_style_to_class_name::convert_style_to_class_name;
8use stylex_css::utils::pre_rule::{sort_at_rules, sort_pseudos};
9
10use super::null_pre_rule::NullPreRule;
11use super::pre_rule_set::PreRuleSet;
12use super::state_manager::StateManager;
13use super::types::ClassesToOriginalPaths;
14use stylex_types::structures::injectable_style::InjectableStyle;
15
16#[derive(Debug, Clone, PartialEq)]
17pub(crate) enum PreRuleValue {
18 Expr(Expr),
19 String(String),
20 Vec(Vec<String>),
21 Null,
22}
23
24#[derive(Debug, Clone, PartialEq)]
25pub(crate) struct ComputedStyle(
26 pub(crate) String,
27 pub(crate) InjectableStyle,
28 pub(crate) ClassesToOriginalPaths,
29);
30
31#[derive(Debug, Clone, PartialEq)]
32pub(crate) enum CompiledResult {
33 Null,
34 ComputedStyles(Vec<ComputedStyle>),
35}
36
37impl CompiledResult {
38 pub(crate) fn _as_computed_styles(&self) -> Option<&Vec<ComputedStyle>> {
39 match self {
40 CompiledResult::ComputedStyles(computed_styles) => Some(computed_styles),
41 _ => None,
42 }
43 }
44}
45
46pub(crate) trait PreRule: Debug {
47 #[allow(dead_code)]
48 fn get_value(&self) -> Option<PreRuleValue>;
49 fn compiled(&mut self, state: &mut StateManager) -> CompiledResult;
50 #[allow(dead_code)]
51 fn equals(&self, other: &dyn PreRule) -> bool;
52}
53
54#[derive(Debug, Clone, PartialEq)]
55pub(crate) enum PreRules {
56 PreRuleSet(PreRuleSet),
57 StylesPreRule(StylesPreRule),
58 NullPreRule(NullPreRule),
59}
60
61#[derive(Debug, Clone, PartialEq)]
62pub(crate) struct StylesPreRule {
63 property: String,
64 value: PreRuleValue,
65 pseudos: Vec<String>,
66 at_rules: Vec<String>,
67 const_rules: Vec<String>,
68 key_path: Vec<String>,
69}
70
71impl StylesPreRule {
72 fn get_pseudos(key_path: &Option<Vec<String>>) -> Vec<String> {
73 let mut unsorted_pseudos = key_path.clone().unwrap_or_default();
74
75 unsorted_pseudos = unsorted_pseudos
76 .iter()
77 .filter(|key| key.starts_with(':') || key.starts_with("["))
78 .cloned()
79 .collect();
80
81 sort_pseudos(&unsorted_pseudos)
82 }
83
84 fn get_at_rules(key_path: &Option<Vec<String>>) -> Vec<String> {
85 let mut unsorted_at_rules = key_path.clone().unwrap_or_default();
86
87 unsorted_at_rules = unsorted_at_rules
88 .iter()
89 .filter(|key| key.starts_with('@'))
90 .cloned()
91 .collect();
92
93 sort_at_rules(&unsorted_at_rules)
94 }
95
96 fn get_const_rules(key_path: &Option<Vec<String>>) -> Vec<String> {
97 let mut unsorted_const_rules = key_path.clone().unwrap_or_default();
98
99 unsorted_const_rules = unsorted_const_rules
100 .iter()
101 .filter(|key| key.starts_with("var(--"))
102 .cloned()
103 .collect();
104
105 sort_at_rules(&unsorted_const_rules)
106 }
107 pub(crate) fn new(property: &str, value: PreRuleValue, key_path: Option<Vec<String>>) -> Self {
108 let property_str = property.to_string();
109
110 StylesPreRule {
111 property: property_str,
112 value,
113 pseudos: StylesPreRule::get_pseudos(&key_path),
114 at_rules: StylesPreRule::get_at_rules(&key_path),
115 const_rules: StylesPreRule::get_const_rules(&key_path),
116 key_path: key_path.unwrap_or_default(),
117 }
118 }
119 pub(crate) fn _get_property(&self) -> Option<&str> {
120 Some(&self.property)
121 }
122 pub(crate) fn _get_pseudos(&self) -> Option<Vec<String>> {
123 Some(self.pseudos.to_owned())
124 }
125 pub(crate) fn _get_at_rules(&self) -> Option<Vec<String>> {
126 Some(self.at_rules.to_owned())
127 }
128}
129
130impl PreRule for StylesPreRule {
131 fn get_value(&self) -> Option<PreRuleValue> {
132 Some(self.value.to_owned())
133 }
134
135 fn compiled(&mut self, state: &mut StateManager) -> CompiledResult {
136 let (_, class_name, rule) = convert_style_to_class_name(
137 (self.property.as_str(), &self.value),
138 &mut self.pseudos,
139 &mut self.at_rules,
140 &mut self.const_rules,
141 state,
142 );
143
144 let mut classes_to_original_paths = IndexMap::new();
145
146 classes_to_original_paths.insert(class_name.clone(), self.key_path.clone());
147
148 CompiledResult::ComputedStyles(vec![ComputedStyle(
149 class_name,
150 rule,
151 classes_to_original_paths,
152 )])
153 }
154
155 fn equals(&self, other: &dyn PreRule) -> bool {
156 type_of(other) == type_of(self)
157 }
158}