1#![warn(missing_docs)]
2
3use std::{
4 collections::HashMap,
5 hash::{Hash, Hasher},
6 rc::Rc,
7};
8
9pub enum TsValue {
11 Undefined,
13 Null,
15 Boolean(bool),
17 Number(f64),
19 String(String),
21 Object(HashMap<String, TsValue>),
23 Array(Vec<TsValue>),
25 Function(Rc<dyn Fn(&[TsValue]) -> TsValue>),
27 Error(String),
29 Union(Vec<TsValue>),
31 Generic(String, Vec<TsValue>),
33 Symbol(String),
35 BigInt(i128),
37 Date(i64),
39 RegExp(String),
41 Map(Vec<(TsValue, TsValue)>),
43 Set(Vec<TsValue>),
45 Promise(Box<TsValue>),
47 Iterable(Box<dyn Iterator<Item = TsValue>>),
49}
50
51impl Clone for TsValue {
52 fn clone(&self) -> Self {
53 match self {
54 TsValue::Undefined => TsValue::Undefined,
55 TsValue::Null => TsValue::Null,
56 TsValue::Boolean(b) => TsValue::Boolean(*b),
57 TsValue::Number(n) => TsValue::Number(*n),
58 TsValue::String(s) => TsValue::String(s.clone()),
59 TsValue::Object(props) => TsValue::Object(props.clone()),
60 TsValue::Array(arr) => TsValue::Array(arr.clone()),
61 TsValue::Function(f) => TsValue::Function(Rc::clone(f)), TsValue::Error(s) => TsValue::Error(s.clone()),
63 TsValue::Union(values) => TsValue::Union(values.clone()),
64 TsValue::Generic(name, args) => TsValue::Generic(name.clone(), args.clone()),
65 TsValue::Symbol(s) => TsValue::Symbol(s.clone()),
66 TsValue::BigInt(bi) => TsValue::BigInt(*bi),
67 TsValue::Date(d) => TsValue::Date(*d),
68 TsValue::RegExp(pattern) => TsValue::RegExp(pattern.clone()),
69 TsValue::Map(entries) => TsValue::Map(entries.clone()),
70 TsValue::Set(values) => TsValue::Set(values.clone()),
71 TsValue::Promise(value) => TsValue::Promise(value.clone()),
72 TsValue::Iterable(_) => TsValue::Undefined, }
74 }
75}
76
77impl std::fmt::Debug for TsValue {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 match self {
80 TsValue::Undefined => write!(f, "Undefined"),
81 TsValue::Null => write!(f, "Null"),
82 TsValue::Boolean(_) => write!(f, "Boolean"),
83 TsValue::Number(_) => write!(f, "Number"),
84 TsValue::String(_) => write!(f, "String"),
85 TsValue::Object(_) => write!(f, "Object"),
86 TsValue::Array(_) => write!(f, "Array"),
87 TsValue::Function(_) => write!(f, "Function"),
88 TsValue::Error(_) => write!(f, "Error"),
89 TsValue::Union(_) => write!(f, "Union"),
90 TsValue::Generic(name, _) => write!(f, "Generic({})", name),
91 TsValue::Symbol(_) => write!(f, "Symbol"),
92 TsValue::BigInt(_) => write!(f, "BigInt"),
93 TsValue::Date(_) => write!(f, "Date"),
94 TsValue::RegExp(_) => write!(f, "RegExp"),
95 TsValue::Map(_) => write!(f, "Map"),
96 TsValue::Set(_) => write!(f, "Set"),
97 TsValue::Promise(_) => write!(f, "Promise"),
98 TsValue::Iterable(_) => write!(f, "Iterable"),
99 }
100 }
101}
102
103impl Hash for TsValue {
104 fn hash<H: Hasher>(&self, state: &mut H) {
105 match self {
106 TsValue::Undefined => 0.hash(state),
107 TsValue::Null => 1.hash(state),
108 TsValue::Boolean(b) => {
109 2.hash(state);
110 b.hash(state);
111 }
112 TsValue::Number(n) => {
113 3.hash(state);
114 n.to_bits().hash(state);
115 }
116 TsValue::String(s) => {
117 4.hash(state);
118 s.hash(state);
119 }
120 TsValue::Object(props) => {
121 5.hash(state);
122 props.len().hash(state);
123 for (key, value) in props {
124 key.hash(state);
125 value.hash(state);
126 }
127 }
128 TsValue::Array(arr) => {
129 6.hash(state);
130 arr.len().hash(state);
131 for item in arr {
132 item.hash(state);
133 }
134 }
135 TsValue::Function(_) => 7.hash(state),
136 TsValue::Error(s) => {
137 8.hash(state);
138 s.hash(state);
139 }
140 TsValue::Union(values) => {
141 9.hash(state);
142 values.len().hash(state);
143 for value in values {
144 value.hash(state);
145 }
146 }
147 TsValue::Generic(name, args) => {
148 10.hash(state);
149 name.hash(state);
150 args.len().hash(state);
151 for arg in args {
152 arg.hash(state);
153 }
154 }
155 TsValue::Symbol(s) => {
156 11.hash(state);
157 s.hash(state);
158 }
159 TsValue::BigInt(bi) => {
160 12.hash(state);
161 bi.hash(state);
162 }
163 TsValue::Date(d) => {
164 13.hash(state);
165 d.hash(state);
166 }
167 TsValue::RegExp(pattern) => {
168 14.hash(state);
169 pattern.hash(state);
170 }
171 TsValue::Map(entries) => {
172 15.hash(state);
173 entries.len().hash(state);
174 for (key, value) in entries {
175 key.hash(state);
176 value.hash(state);
177 }
178 }
179 TsValue::Set(values) => {
180 16.hash(state);
181 values.len().hash(state);
182 for value in values {
183 value.hash(state);
184 }
185 }
186 TsValue::Promise(value) => {
187 17.hash(state);
188 value.hash(state);
189 }
190 TsValue::Iterable(_) => 18.hash(state),
191 }
192 }
193}
194
195impl TsValue {
196 pub fn is_undefined(&self) -> bool {
198 matches!(self, TsValue::Undefined)
199 }
200
201 pub fn is_null(&self) -> bool {
203 matches!(self, TsValue::Null)
204 }
205
206 pub fn is_boolean(&self) -> bool {
208 matches!(self, TsValue::Boolean(_))
209 }
210
211 pub fn is_number(&self) -> bool {
213 matches!(self, TsValue::Number(_))
214 }
215
216 pub fn is_string(&self) -> bool {
218 matches!(self, TsValue::String(_))
219 }
220
221 pub fn is_object(&self) -> bool {
223 matches!(self, TsValue::Object(_))
224 }
225
226 pub fn is_array(&self) -> bool {
228 matches!(self, TsValue::Array(_))
229 }
230
231 pub fn is_function(&self) -> bool {
233 matches!(self, TsValue::Function(_))
234 }
235
236 pub fn is_error(&self) -> bool {
238 matches!(self, TsValue::Error(_))
239 }
240
241 pub fn is_union(&self) -> bool {
243 matches!(self, TsValue::Union(_))
244 }
245
246 pub fn is_generic(&self) -> bool {
248 matches!(self, TsValue::Generic(_, _))
249 }
250
251 pub fn is_symbol(&self) -> bool {
253 matches!(self, TsValue::Symbol(_))
254 }
255
256 pub fn is_bigint(&self) -> bool {
258 matches!(self, TsValue::BigInt(_))
259 }
260
261 pub fn is_date(&self) -> bool {
263 matches!(self, TsValue::Date(_))
264 }
265
266 pub fn is_regexp(&self) -> bool {
268 matches!(self, TsValue::RegExp(_))
269 }
270
271 pub fn is_map(&self) -> bool {
273 matches!(self, TsValue::Map(_))
274 }
275
276 pub fn is_set(&self) -> bool {
278 matches!(self, TsValue::Set(_))
279 }
280
281 pub fn is_promise(&self) -> bool {
283 matches!(self, TsValue::Promise(_))
284 }
285
286 pub fn is_iterable(&self) -> bool {
288 matches!(self, TsValue::Iterable(_))
289 }
290
291 pub fn to_boolean(&self) -> bool {
293 match self {
294 TsValue::Undefined => false,
295 TsValue::Null => false,
296 TsValue::Boolean(b) => *b,
297 TsValue::Number(n) => *n != 0.0 && !n.is_nan(),
298 TsValue::String(s) => !s.is_empty(),
299 TsValue::Object(_) => true,
300 TsValue::Array(_) => true,
301 TsValue::Function(_) => true,
302 TsValue::Error(_) => true,
303 TsValue::Union(values) => !values.is_empty(),
304 TsValue::Generic(_, _) => true,
305 TsValue::Symbol(_) => true,
306 TsValue::BigInt(bi) => *bi != 0,
307 TsValue::Date(_) => true,
308 TsValue::RegExp(_) => true,
309 TsValue::Map(entries) => !entries.is_empty(),
310 TsValue::Set(values) => !values.is_empty(),
311 TsValue::Promise(_) => true,
312 TsValue::Iterable(_) => true,
313 }
314 }
315
316 pub fn to_number(&self) -> f64 {
318 match self {
319 TsValue::Undefined => f64::NAN,
320 TsValue::Null => 0.0,
321 TsValue::Boolean(b) => {
322 if *b {
323 1.0
324 }
325 else {
326 0.0
327 }
328 }
329 TsValue::Number(n) => *n,
330 TsValue::String(s) => s.parse().unwrap_or(f64::NAN),
331 TsValue::Object(_) => f64::NAN,
332 TsValue::Array(_) => {
333 if let TsValue::Array(arr) = self {
334 if arr.is_empty() { 0.0 } else { f64::NAN }
335 }
336 else {
337 f64::NAN
338 }
339 }
340 TsValue::Function(_) => f64::NAN,
341 TsValue::Error(_) => f64::NAN,
342 TsValue::Union(values) => {
343 if values.is_empty() {
344 0.0
345 }
346 else {
347 values[0].to_number()
348 }
349 }
350 TsValue::Generic(_, _) => f64::NAN,
351 TsValue::Symbol(_) => f64::NAN,
352 TsValue::BigInt(bi) => *bi as f64,
353 TsValue::Date(d) => *d as f64,
354 TsValue::RegExp(_) => f64::NAN,
355 TsValue::Map(_) => f64::NAN,
356 TsValue::Set(_) => f64::NAN,
357 TsValue::Promise(_) => f64::NAN,
358 TsValue::Iterable(_) => f64::NAN,
359 }
360 }
361
362 pub fn to_string(&self) -> String {
364 match self {
365 TsValue::Undefined => "undefined".to_string(),
366 TsValue::Null => "null".to_string(),
367 TsValue::Boolean(b) => b.to_string(),
368 TsValue::Number(n) => n.to_string(),
369 TsValue::String(s) => s.clone(),
370 TsValue::Object(_) => "[object Object]".to_string(),
371 TsValue::Array(_) => {
372 if let TsValue::Array(arr) = self {
373 let elements: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
374 format!("[{}]", elements.join(", "))
375 }
376 else {
377 "[object Array]".to_string()
378 }
379 }
380 TsValue::Function(_) => "[Function]".to_string(),
381 TsValue::Error(s) => format!("Error: {}", s),
382 TsValue::Union(values) => {
383 let elements: Vec<String> = values.iter().map(|v| v.to_string()).collect();
384 format!("Union({})", elements.join(", "))
385 }
386 TsValue::Generic(name, args) => {
387 let args_str: Vec<String> = args.iter().map(|v| v.to_string()).collect();
388 format!("{}{{ {} }}", name, args_str.join(", "))
389 }
390 TsValue::Symbol(s) => format!("Symbol({})", s),
391 TsValue::BigInt(bi) => bi.to_string(),
392 TsValue::Date(d) => format!("Date({})", d),
393 TsValue::RegExp(pattern) => format!("/{}/", pattern),
394 TsValue::Map(entries) => {
395 let entries_str: Vec<String> =
396 entries.iter().map(|(k, v)| format!("{}: {}", k.to_string(), v.to_string())).collect();
397 format!("Map({})", entries_str.join(", "))
398 }
399 TsValue::Set(values) => {
400 let values_str: Vec<String> = values.iter().map(|v| v.to_string()).collect();
401 format!("Set({})", values_str.join(", "))
402 }
403 TsValue::Promise(value) => format!("Promise<{}>", value.to_string()),
404 TsValue::Iterable(_) => "[object Iterable]".to_string(),
405 }
406 }
407}
408
409#[derive(Debug, Clone)]
411pub enum TsError {
412 TypeError(String),
414 ReferenceError(String),
416 SyntaxError(String),
418 RangeError(String),
420 Other(String),
422}
423
424impl std::fmt::Display for TsError {
425 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
426 match self {
427 TsError::TypeError(msg) => write!(f, "TypeError: {}", msg),
428 TsError::ReferenceError(msg) => write!(f, "ReferenceError: {}", msg),
429 TsError::SyntaxError(msg) => write!(f, "SyntaxError: {}", msg),
430 TsError::RangeError(msg) => write!(f, "RangeError: {}", msg),
431 TsError::Other(msg) => write!(f, "Error: {}", msg),
432 }
433 }
434}
435
436pub trait ToTsValue {
438 fn to_ts_value(&self) -> TsValue;
440}
441
442impl ToTsValue for bool {
443 fn to_ts_value(&self) -> TsValue {
444 TsValue::Boolean(*self)
445 }
446}
447
448impl ToTsValue for f64 {
449 fn to_ts_value(&self) -> TsValue {
450 TsValue::Number(*self)
451 }
452}
453
454impl ToTsValue for i32 {
455 fn to_ts_value(&self) -> TsValue {
456 TsValue::Number(*self as f64)
457 }
458}
459
460impl ToTsValue for &str {
461 fn to_ts_value(&self) -> TsValue {
462 TsValue::String(self.to_string())
463 }
464}
465
466impl ToTsValue for String {
467 fn to_ts_value(&self) -> TsValue {
468 TsValue::String(self.clone())
469 }
470}
471
472impl<T: ToTsValue> ToTsValue for Vec<T> {
473 fn to_ts_value(&self) -> TsValue {
474 let values: Vec<TsValue> = self.iter().map(|v| v.to_ts_value()).collect();
475 TsValue::Array(values)
476 }
477}
478
479impl<K: ToString, V: ToTsValue> ToTsValue for Vec<(K, V)> {
480 fn to_ts_value(&self) -> TsValue {
481 let mut map = HashMap::new();
482 for (k, v) in self {
483 map.insert(k.to_string(), v.to_ts_value());
484 }
485 TsValue::Object(map)
486 }
487}
488
489impl ToTsValue for i128 {
490 fn to_ts_value(&self) -> TsValue {
491 TsValue::BigInt(*self)
492 }
493}
494
495impl ToTsValue for i64 {
496 fn to_ts_value(&self) -> TsValue {
497 TsValue::Date(*self)
498 }
499}
500
501impl<T: ToTsValue> ToTsValue for Option<T> {
502 fn to_ts_value(&self) -> TsValue {
503 match self {
504 Some(value) => value.to_ts_value(),
505 None => TsValue::Null,
506 }
507 }
508}
509
510impl<T: ToTsValue, E: ToString> ToTsValue for Result<T, E> {
511 fn to_ts_value(&self) -> TsValue {
512 match self {
513 Ok(value) => value.to_ts_value(),
514 Err(error) => TsValue::Error(error.to_string()),
515 }
516 }
517}
518
519impl ToTsValue for std::collections::HashMap<String, TsValue> {
520 fn to_ts_value(&self) -> TsValue {
521 TsValue::Object(self.clone())
522 }
523}
524
525impl ToTsValue for std::collections::HashSet<TsValue> {
526 fn to_ts_value(&self) -> TsValue {
527 let values: Vec<TsValue> = self.iter().cloned().collect();
528 TsValue::Set(values)
529 }
530}
531
532impl ToTsValue for std::collections::HashMap<TsValue, TsValue> {
533 fn to_ts_value(&self) -> TsValue {
534 let entries: Vec<(TsValue, TsValue)> = self.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
535 TsValue::Map(entries)
536 }
537}
538
539unsafe impl Send for TsValue {}
541
542unsafe impl Sync for TsValue {}