Skip to main content

stylex_transform/shared/structures/
pre_rule.rs

1use 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}