stylex_transform/shared/structures/
theme_ref.rs1use rustc_hash::FxHashMap;
2use stylex_macros::stylex_panic;
3
4use crate::shared::utils::common::{create_hash, gen_file_based_identifier};
5use stylex_constants::constants::common::VAR_GROUP_HASH_KEY;
6use stylex_enums::theme_ref::ThemeRefResult;
7
8use super::state_manager::StateManager;
9
10#[derive(Debug, Clone)]
11pub struct ThemeRef {
12 file_name: String,
13 export_name: String,
14 class_name_prefix: String,
15 map: FxHashMap<String, String>,
16}
17
18impl ThemeRef {
19 pub(crate) fn new(file_name: String, export_name: String, class_name_prefix: String) -> Self {
20 Self {
21 file_name,
22 export_name,
23 class_name_prefix,
24 map: FxHashMap::default(),
25 }
26 }
27
28 pub(crate) fn get(&mut self, key: &str, state: &StateManager) -> ThemeRefResult {
29 if key == "__IS_PROXY" {
30 return ThemeRefResult::Proxy;
31 }
32
33 if key == "toString" {
34 let value = format!(
35 "{}{}",
36 state.options.class_name_prefix,
37 create_hash(&gen_file_based_identifier(
38 &self.file_name,
39 &self.export_name,
40 None
41 ))
42 );
43 return ThemeRefResult::ToString(value);
44 }
45
46 if key.starts_with("--") {
47 let css_key = format!("var({})", key);
48 return ThemeRefResult::CssVar(css_key);
49 }
50 let entry = self.map.entry(key.to_string()).or_insert_with(|| {
51 let str_to_hash = gen_file_based_identifier(
52 &self.file_name,
53 &self.export_name,
54 if key == VAR_GROUP_HASH_KEY {
55 None
56 } else {
57 Some(key)
58 },
59 );
60
61 let debug = state.options.debug;
62 let enable_debug_class_names = state.options.enable_debug_class_names;
63
64 let var_safe_key = if key == VAR_GROUP_HASH_KEY {
65 String::new()
66 } else {
67 let mut safe = if key.chars().next().unwrap_or('\0').is_ascii_digit() {
68 format!("_{}", key)
69 } else {
70 key.to_string()
71 }
72 .chars()
73 .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
74 .collect::<String>();
75
76 safe.push('-');
77
78 safe
79 };
80
81 let var_name = if debug && enable_debug_class_names {
82 format!(
83 "{}{}{}",
84 var_safe_key,
85 self.class_name_prefix,
86 create_hash(&str_to_hash)
87 )
88 } else {
89 format!("{}{}", self.class_name_prefix, create_hash(&str_to_hash))
90 };
91
92 if key == VAR_GROUP_HASH_KEY {
93 return var_name;
94 }
95
96 format!("var(--{})", var_name)
97 });
98
99 ThemeRefResult::CssVar(entry.to_string())
100 }
101
102 fn _set(&self, key: &str, value: &str) {
103 stylex_panic!(
104 "Cannot set value {} to key {} in theme {}",
105 value,
106 key,
107 self.file_name
108 );
109 }
110}
111
112impl PartialEq for ThemeRef {
113 fn eq(&self, _other: &Self) -> bool {
114 stylex_panic!("Theme references cannot be compared directly.");
115 }
117}