Skip to main content

stylex_transform/shared/structures/
functions.rs

1use std::{fmt::Debug, rc::Rc, sync::Arc};
2
3use indexmap::IndexMap;
4use rustc_hash::FxHashMap;
5use swc_core::{atoms::Atom, ecma::ast::Expr};
6
7use crate::shared::structures::types::FlatCompiledStyles;
8use stylex_enums::js::{ArrayJS, MathJS, ObjectJS, StringJS};
9use stylex_enums::value_with_default::ValueWithDefault;
10
11use super::types::{FunctionMapIdentifiers, FunctionMapMemberExpression};
12use stylex_structures::stylex_env::JSFunction;
13
14use stylex_types::traits::StyleOptions;
15
16#[derive(Debug, Hash, PartialEq, Clone)]
17pub enum CallbackType {
18  Array(ArrayJS),
19  Object(ObjectJS),
20  Math(MathJS),
21  String(StringJS),
22  Custom(Expr),
23}
24
25pub type StylexTypeFn = Rc<dyn Fn(ValueWithDefault) -> Expr + 'static>;
26pub type StylexExprFn = fn(Expr, &mut dyn StyleOptions) -> Expr;
27
28pub enum FunctionType {
29  ArrayArgs(fn(Vec<Expr>, &mut dyn StyleOptions, &FunctionMap) -> Expr),
30  StylexExprFn(StylexExprFn),
31  StylexTypeFn(StylexTypeFn),
32  StylexFnsFactory(fn(input: String) -> StylexTypeFn),
33
34  Mapper(Rc<dyn Fn() -> Expr + 'static>),
35  Callback(Box<CallbackType>),
36  DefaultMarker(Arc<IndexMap<String, StylexExprFn>>),
37  /// An env function from the `env` config option.
38  /// Takes evaluated arguments as `Expr`s and returns an `Expr`.
39  EnvFunction(JSFunction),
40}
41
42impl Clone for FunctionType {
43  fn clone(&self) -> Self {
44    match self {
45      Self::ArrayArgs(e) => Self::ArrayArgs(*e),
46      Self::StylexExprFn(e) => Self::StylexExprFn(*e),
47      Self::StylexTypeFn(e) => Self::StylexTypeFn(e.clone()),
48      Self::StylexFnsFactory(e) => Self::StylexFnsFactory(*e),
49      Self::Callback(v) => Self::Callback(v.clone()),
50      Self::Mapper(c) => Self::Mapper(Rc::clone(c)),
51      Self::DefaultMarker(e) => Self::DefaultMarker(Arc::clone(e)),
52      Self::EnvFunction(e) => Self::EnvFunction(e.clone()),
53    }
54  }
55}
56
57impl std::fmt::Debug for FunctionType {
58  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59    match self {
60      FunctionType::ArrayArgs(_) => write!(f, "ArrayArgs"),
61      FunctionType::StylexExprFn(_) => write!(f, "StylexExprWithStateFn"),
62      FunctionType::StylexTypeFn(_) => write!(f, "StylexExprFn"),
63      FunctionType::StylexFnsFactory(_) => write!(f, "StylexFnsFactory"),
64      FunctionType::Mapper(_) => write!(f, "Mapper"),
65      FunctionType::Callback(_) => write!(f, "Callback"),
66      FunctionType::DefaultMarker(_) => write!(f, "DefaultMarker"),
67      FunctionType::EnvFunction(_) => write!(f, "EnvFunction"),
68    }
69  }
70}
71
72impl PartialEq for FunctionType {
73  fn eq(&self, other: &Self) -> bool {
74    match (self, other) {
75      (FunctionType::ArrayArgs(_), FunctionType::ArrayArgs(_)) => false,
76      (FunctionType::StylexExprFn(_), FunctionType::StylexExprFn(_)) => false,
77      (FunctionType::StylexTypeFn(_), FunctionType::StylexTypeFn(_)) => false,
78      (FunctionType::StylexFnsFactory(_), FunctionType::StylexFnsFactory(_)) => false,
79      (FunctionType::Mapper(_), FunctionType::StylexExprFn(_)) => false,
80      (FunctionType::Callback(_), FunctionType::Callback(_)) => false,
81      (FunctionType::DefaultMarker(_), FunctionType::DefaultMarker(_)) => false,
82      (FunctionType::EnvFunction(_), FunctionType::EnvFunction(_)) => false,
83      _ => false,
84    }
85  }
86}
87
88impl std::hash::Hash for FunctionType {
89  fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
90    std::mem::discriminant(self).hash(state);
91  }
92}
93
94#[derive(Debug, Hash, PartialEq, Clone)]
95pub struct FunctionConfig {
96  pub fn_ptr: FunctionType,
97  pub takes_path: bool,
98}
99
100pub enum FunctionConfigType {
101  Regular(FunctionConfig),
102  Map(FxHashMap<Atom, FunctionConfig>),
103  IndexMap(FlatCompiledStyles),
104  /// An env object from the `env` config option. Contains both values and functions.
105  EnvObject(IndexMap<String, stylex_structures::stylex_env::EnvEntry>),
106}
107
108impl std::fmt::Debug for FunctionConfigType {
109  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110    match self {
111      Self::Regular(config) => f.debug_tuple("Regular").field(config).finish(),
112      Self::Map(map) => f.debug_tuple("Map").field(map).finish(),
113      Self::IndexMap(map) => f.debug_tuple("IndexMap").field(map).finish(),
114      Self::EnvObject(map) => f.debug_tuple("EnvObject").field(map).finish(),
115    }
116  }
117}
118
119impl Clone for FunctionConfigType {
120  fn clone(&self) -> Self {
121    match self {
122      Self::Regular(config) => Self::Regular(config.clone()),
123      Self::Map(map) => Self::Map(map.clone()),
124      Self::IndexMap(map) => Self::IndexMap(map.clone()),
125      Self::EnvObject(map) => Self::EnvObject(map.clone()),
126    }
127  }
128}
129
130impl PartialEq for FunctionConfigType {
131  fn eq(&self, other: &Self) -> bool {
132    match (self, other) {
133      (Self::Regular(a), Self::Regular(b)) => a == b,
134      (Self::Map(a), Self::Map(b)) => a == b,
135      (Self::IndexMap(a), Self::IndexMap(b)) => a == b,
136      (Self::EnvObject(_), Self::EnvObject(_)) => false,
137      _ => false,
138    }
139  }
140}
141
142impl FunctionConfigType {
143  pub(crate) fn _as_function_config(&self) -> Option<&FunctionConfig> {
144    match self {
145      Self::Regular(config) => Some(config),
146      Self::Map(_) | Self::IndexMap(_) | Self::EnvObject(_) => None,
147    }
148  }
149
150  pub(crate) fn _as_map(&self) -> Option<&FxHashMap<Atom, FunctionConfig>> {
151    match self {
152      Self::Map(map) => Some(map),
153      Self::Regular(_) | Self::IndexMap(_) | Self::EnvObject(_) => None,
154    }
155  }
156
157  pub(crate) fn as_map_mut(&mut self) -> Option<&mut FxHashMap<Atom, FunctionConfig>> {
158    match self {
159      Self::Map(map) => Some(map),
160      Self::Regular(_) | Self::IndexMap(_) | Self::EnvObject(_) => None,
161    }
162  }
163
164  pub(crate) fn _as_function_config_mut(&mut self) -> Option<&mut FunctionConfig> {
165    match self {
166      Self::Regular(config) => Some(config),
167      Self::Map(_) | Self::IndexMap(_) | Self::EnvObject(_) => None,
168    }
169  }
170
171  pub(crate) fn _as_index_map(&self) -> Option<&FlatCompiledStyles> {
172    match self {
173      Self::IndexMap(map) => Some(map),
174      Self::Regular(_) | Self::Map(_) | Self::EnvObject(_) => None,
175    }
176  }
177
178  pub(crate) fn _as_index_map_mut(&mut self) -> Option<&mut FlatCompiledStyles> {
179    match self {
180      Self::IndexMap(map) => Some(map),
181      Self::Regular(_) | Self::Map(_) | Self::EnvObject(_) => None,
182    }
183  }
184}
185
186#[derive(Debug, PartialEq, Clone, Default)]
187pub struct FunctionMap {
188  pub identifiers: FunctionMapIdentifiers,
189  pub member_expressions: FunctionMapMemberExpression,
190  /// If `true`, disables the generation or processing of imports for this function map.
191  /// Set to `true` when imports should not be generated (e.g., for built-in or inlined functions).
192  /// Set to `false` to allow normal import handling.
193  pub disable_imports: bool,
194}