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