1use std::fmt;
2use std::fmt::{Display, Formatter};
3use std::rc::Rc;
4
5use crate::runner::ds::object::JsObjectType;
6use crate::runner::ds::operations::type_conversion::{TYPE_STR_NULL, TYPE_STR_UNDEFINED};
7use crate::runner::ds::symbol::SymbolData;
8
9pub enum JsValue {
26 Undefined,
28 Null,
30 Boolean(bool),
32 String(String),
34 Symbol(SymbolData),
36 Number(JsNumberType),
38 Object(JsObjectType),
40}
41impl Clone for JsValue {
42 fn clone(&self) -> Self {
43 match self {
44 JsValue::Undefined => JsValue::Undefined,
45 JsValue::String(d) => JsValue::String(d.to_string()),
46 JsValue::Boolean(d) => JsValue::Boolean(*d),
47 JsValue::Null => JsValue::Null,
48 JsValue::Number(d) => JsValue::Number(d.clone()),
49 JsValue::Object(o) => JsValue::Object(o.clone()),
50 JsValue::Symbol(d) => JsValue::Symbol(d.clone()),
51 }
52 }
53}
54impl Display for JsValue {
55 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
56 write!(
57 f,
58 "{}",
59 match self {
60 JsValue::Undefined => TYPE_STR_UNDEFINED.to_string(),
61 JsValue::Null => TYPE_STR_NULL.to_string(),
62 JsValue::Boolean(b) => format!("bool({})", b),
63 JsValue::String(s) => format!("\"{}\"", s),
64 JsValue::Symbol(s) => s.to_string(),
65 JsValue::Number(n) => n.to_string(),
66 JsValue::Object(o) => (**o).borrow().as_js_object().to_string(),
67 }
68 )
69 }
70}
71
72impl fmt::Debug for JsValue {
73 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
74 match self {
75 JsValue::Undefined => write!(f, "JsValue::Undefined"),
76 JsValue::Null => write!(f, "JsValue::Null"),
77 JsValue::Boolean(b) => write!(f, "JsValue::Boolean({})", b),
78 JsValue::String(s) => write!(f, "JsValue::String({:?})", s),
79 JsValue::Symbol(s) => write!(f, "JsValue::Symbol({})", s),
80 JsValue::Number(n) => write!(f, "JsValue::Number({:?})", n),
81 JsValue::Object(_) => write!(f, "JsValue::Object(...)"),
82 }
83 }
84}
85
86impl PartialEq for JsValue {
87 fn eq(&self, other: &Self) -> bool {
88 match (self, other) {
89 (JsValue::Undefined, JsValue::Undefined) => true,
90 (JsValue::Null, JsValue::Null) => true,
91 (JsValue::Boolean(a), JsValue::Boolean(b)) => a == b,
92 (JsValue::String(a), JsValue::String(b)) => a == b,
93 (JsValue::Number(a), JsValue::Number(b)) => a == b,
94 (JsValue::Object(a), JsValue::Object(b)) => Rc::ptr_eq(a, b),
95 (JsValue::Symbol(a), JsValue::Symbol(b)) => a == b,
96 _ => false,
97 }
98 }
99}
100
101#[derive(Debug, PartialEq)]
116pub enum JsNumberType {
117 Integer(i64),
119 Float(f64),
120 NaN,
121 PositiveInfinity,
122 NegativeInfinity,
123}
124impl Display for JsNumberType {
125 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
126 match self {
127 JsNumberType::Integer(i) => write!(f, "{}", i),
128 JsNumberType::Float(nf) => write!(f, "{}", nf),
129 JsNumberType::NaN => write!(f, "NaN"),
130 JsNumberType::PositiveInfinity => write!(f, "+Infinity"),
131 JsNumberType::NegativeInfinity => write!(f, "-Infinity"),
132 }
133 }
134}
135impl Clone for JsNumberType {
136 fn clone(&self) -> Self {
137 match self {
138 JsNumberType::Integer(i) => JsNumberType::Integer(*i),
139 JsNumberType::Float(nf) => JsNumberType::Float(*nf),
140 JsNumberType::NaN => JsNumberType::NaN,
141 JsNumberType::PositiveInfinity => JsNumberType::PositiveInfinity,
142 JsNumberType::NegativeInfinity => JsNumberType::NegativeInfinity,
143 }
144 }
145}
146
147pub enum JsValueOrSelf<'a> {
148 ValueRef(&'a JsValue),
149 SelfValue,
150}