js_deobfuscator/value/
mod.rs1pub mod ops;
7pub mod coerce;
8pub mod string;
9pub mod array;
10pub mod math;
11pub mod number;
12pub mod json;
13pub mod uri;
14pub mod runtime;
15
16#[derive(Debug, Clone, PartialEq)]
28pub enum JsValue {
29 Number(f64),
30 String(String),
31 Boolean(bool),
32 Null,
33 Undefined,
34}
35
36impl std::fmt::Display for JsValue {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 Self::Number(n) => write!(f, "{}", coerce::number_to_string(*n)),
44 Self::String(s) => write!(f, "{s}"),
45 Self::Boolean(b) => write!(f, "{b}"),
46 Self::Null => write!(f, "null"),
47 Self::Undefined => write!(f, "undefined"),
48 }
49 }
50}
51
52impl JsValue {
57 #[inline]
61 pub fn is_falsy(&self) -> bool {
62 match self {
63 Self::Boolean(false) | Self::Null | Self::Undefined => true,
64 Self::Number(n) => *n == 0.0 || n.is_nan(),
65 Self::String(s) => s.is_empty(),
66 Self::Boolean(true) => false,
67 }
68 }
69
70 #[inline]
72 pub fn is_truthy(&self) -> bool {
73 !self.is_falsy()
74 }
75
76 #[inline]
78 pub fn type_of(&self) -> &'static str {
79 match self {
80 Self::Number(_) => "number",
81 Self::String(_) => "string",
82 Self::Boolean(_) => "boolean",
83 Self::Null => "object",
84 Self::Undefined => "undefined",
85 }
86 }
87}
88
89#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_falsy_values() {
99 assert!(JsValue::Boolean(false).is_falsy());
100 assert!(JsValue::Number(0.0).is_falsy());
101 assert!(JsValue::Number(-0.0).is_falsy());
102 assert!(JsValue::Number(f64::NAN).is_falsy());
103 assert!(JsValue::String(String::new()).is_falsy());
104 assert!(JsValue::Null.is_falsy());
105 assert!(JsValue::Undefined.is_falsy());
106 }
107
108 #[test]
109 fn test_truthy_values() {
110 assert!(JsValue::Boolean(true).is_truthy());
111 assert!(JsValue::Number(1.0).is_truthy());
112 assert!(JsValue::Number(-1.0).is_truthy());
113 assert!(JsValue::String("x".into()).is_truthy());
114 assert!(JsValue::String("false".into()).is_truthy());
115 }
116
117 #[test]
118 fn test_typeof() {
119 assert_eq!(JsValue::Number(1.0).type_of(), "number");
120 assert_eq!(JsValue::String("x".into()).type_of(), "string");
121 assert_eq!(JsValue::Boolean(true).type_of(), "boolean");
122 assert_eq!(JsValue::Null.type_of(), "object");
123 assert_eq!(JsValue::Undefined.type_of(), "undefined");
124 }
125
126 #[test]
127 fn test_display() {
128 assert_eq!(JsValue::Number(42.0).to_string(), "42");
129 assert_eq!(JsValue::Number(-0.5).to_string(), "-0.5");
130 assert_eq!(JsValue::String("hello".into()).to_string(), "hello");
131 assert_eq!(JsValue::Boolean(true).to_string(), "true");
132 assert_eq!(JsValue::Null.to_string(), "null");
133 assert_eq!(JsValue::Undefined.to_string(), "undefined");
134 }
135}