stylex_evaluator/
common.rs1use std::collections::hash_map::DefaultHasher;
2use std::hash::{Hash, Hasher};
3use std::path::PathBuf;
4
5use radix_fmt::radix;
6use stylex_macros::stylex_panic;
7use swc_core::ecma::{
8 ast::{BinaryOp, Expr, VarDeclarator},
9 utils::drop_span,
10};
11
12pub fn create_hash(value: &str) -> String {
13 radix(murmur2::murmur2(value.as_bytes(), 1), 36).to_string()
14}
15
16pub fn wrap_key_in_quotes(key: &str, should_wrap_in_quotes: bool) -> String {
17 if should_wrap_in_quotes {
18 format!("\"{}\"", key)
19 } else {
20 key.to_string()
21 }
22}
23
24pub fn get_expr_from_var_decl(var_decl: &VarDeclarator) -> &Expr {
25 match &var_decl.init {
26 Some(var_decl_init) => var_decl_init,
27 None => stylex_panic!("Variable declaration must be initialized with an expression."),
28 }
29}
30
31pub fn evaluate_bin_expr(op: BinaryOp, left: f64, right: f64) -> f64 {
32 match &op {
33 BinaryOp::Add => left + right,
34 BinaryOp::Sub => left - right,
35 BinaryOp::Div => left / right,
36 BinaryOp::Mul => left * right,
37 BinaryOp::Mod => left % right,
38 BinaryOp::Exp => left.powf(right),
39 BinaryOp::BitOr => (left as i64 | right as i64) as f64,
40 BinaryOp::BitXor => (left as i64 ^ right as i64) as f64,
41 BinaryOp::BitAnd => (left as i64 & right as i64) as f64,
42 BinaryOp::LShift => ((left as i64) << (right as u64)) as f64,
43 BinaryOp::RShift => ((left as i64) >> (right as u64)) as f64,
44 BinaryOp::ZeroFillRShift => ((left as u64) >> (right as u64)) as f64,
45 _ => stylex_panic!("Unsupported binary operator: {:?}", op),
46 }
47}
48
49pub fn hash_f64(value: f64) -> u64 {
50 let bits = value.to_bits();
51 let mut hasher = DefaultHasher::new();
52 bits.hash(&mut hasher);
53 hasher.finish()
54}
55
56pub fn round_f64(value: f64, decimal_places: u32) -> f64 {
57 let multiplier = 10f64.powi(decimal_places as i32);
58 (value * multiplier).round() / multiplier
59}
60
61pub fn normalize_expr(expr: &mut Expr) -> &mut Expr {
62 match expr {
63 Expr::Paren(paren) => normalize_expr(paren.expr.as_mut()),
64 _ => {
65 *expr = drop_span(expr.clone());
66 expr
67 },
68 }
69}
70
71pub fn sort_numbers_factory() -> impl FnMut(&f64, &f64) -> std::cmp::Ordering {
72 |a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)
73}
74
75pub fn char_code_at(s: &str, index: usize) -> Option<u32> {
76 s.chars().nth(index).map(|c| c as u32)
77}
78
79pub fn stable_hash<T: Hash>(t: &T) -> u64 {
80 let mut hasher = DefaultHasher::new();
81 t.hash(&mut hasher);
82 hasher.finish()
83}
84
85pub fn find_and_swap_remove<T, F>(vec: &mut Vec<T>, predicate: F) -> Option<T>
86where
87 F: FnMut(&T) -> bool,
88{
89 vec
90 .iter()
91 .position(predicate)
92 .map(|index| vec.swap_remove(index))
93}
94
95pub fn create_short_hash(value: &str) -> String {
96 let hash = murmur2::murmur2(value.as_bytes(), 1) % (62u32.pow(5));
97 base62::encode(hash)
98}
99
100pub fn resolve_node_package_path(package_name: &str) -> Result<PathBuf, String> {
101 match node_resolve::Resolver::default()
102 .with_basedir(PathBuf::from("./cwd"))
103 .preserve_symlinks(true)
104 .with_extensions([".ts", ".tsx", ".js", ".jsx", ".json"])
105 .with_main_fields(vec![String::from("main"), String::from("module")])
106 .resolve(package_name)
107 {
108 Ok(path) => Ok(path),
109 Err(error) => Err(format!(
110 "Error resolving package {}: {:?}",
111 package_name, error
112 )),
113 }
114}