1use crate::*;
2use std::iter::FromIterator;
3use std::ops::{Deref, DerefMut};
4use std::{fmt, slice, vec};
5
6#[derive(Clone)]
13pub enum Value {
14 Undefined,
16 Null,
18 Boolean(bool),
20 Number(f64),
22 Date(f64),
24 String(String),
26 Array(Array),
28 Function(Function),
30 Object(Object),
33}
34
35impl Value {
36 pub fn is_undefined(&self) -> bool {
38 if let Value::Undefined = *self { true } else { false }
39 }
40
41 pub fn is_null(&self) -> bool {
43 if let Value::Null = *self { true } else { false }
44 }
45
46 pub fn is_boolean(&self) -> bool {
48 if let Value::Boolean(_) = *self { true } else { false }
49 }
50
51 pub fn is_number(&self) -> bool {
53 if let Value::Number(_) = *self { true } else { false }
54 }
55
56 pub fn is_date(&self) -> bool {
58 if let Value::Date(_) = *self { true } else { false }
59 }
60
61 pub fn is_string(&self) -> bool {
63 if let Value::String(_) = *self { true } else { false }
64 }
65
66 pub fn is_array(&self) -> bool {
68 if let Value::Array(_) = *self { true } else { false }
69 }
70
71 pub fn is_function(&self) -> bool {
73 if let Value::Function(_) = *self { true } else { false }
74 }
75
76 pub fn is_object(&self) -> bool {
78 if let Value::Object(_) = *self { true } else { false }
79 }
80
81 pub fn as_undefined(&self) -> Option<()> {
83 if let Value::Undefined = *self { Some(()) } else { None }
84 }
85
86 pub fn as_null(&self) -> Option<()> {
88 if let Value::Undefined = *self { Some(()) } else { None }
89 }
90
91 pub fn as_boolean(&self) -> Option<bool> {
93 if let Value::Boolean(value) = *self { Some(value) } else { None }
94 }
95
96 pub fn as_number(&self) -> Option<f64> {
98 if let Value::Number(value) = *self { Some(value) } else { None }
99 }
100
101 pub fn as_date(&self) -> Option<f64> {
103 if let Value::Date(value) = *self { Some(value) } else { None }
104 }
105
106 pub fn as_string(&self) -> Option<&String> {
108 if let Value::String(ref value) = *self { Some(value) } else { None }
109 }
110
111 pub fn as_array(&self) -> Option<&Array> {
113 if let Value::Array(ref value) = *self { Some(value) } else { None }
114 }
115
116 pub fn as_function(&self) -> Option<&Function> {
118 if let Value::Function(ref value) = *self { Some(value) } else { None }
119 }
120
121 pub fn as_object(&self) -> Option<&Object> {
123 if let Value::Object(ref value) = *self { Some(value) } else { None }
124 }
125
126 pub fn into<T: FromValue>(self, mv8: &MiniV8) -> Result< T> {
128 T::from_value(self, mv8)
129 }
130
131 pub fn coerce_boolean(&self, mv8: &MiniV8) -> bool {
133 match self {
134 &Value::Boolean(b) => b,
135 value => mv8.scope(|scope| value.to_v8_value(scope).boolean_value(scope)),
136 }
137 }
138
139 pub fn coerce_number(&self, mv8: &MiniV8) -> Result<f64> {
145 match self {
146 &Value::Number(n) => Ok(n),
147 value => mv8.try_catch(|scope| {
148 let maybe = value.to_v8_value(scope).to_number(scope);
149 mv8.exception(scope).map(|_| maybe.unwrap().value())
150 }),
151 }
152 }
153
154 pub fn coerce_string(&self, mv8: &MiniV8) -> Result<String> {
158 match self {
159 &Value::String(ref s) => Ok(s.clone()),
160 value => mv8.try_catch(|scope| {
161 let maybe = value.to_v8_value(scope).to_string(scope);
162 mv8.exception(scope).map(|_| String {
163 mv8: mv8.clone(),
164 handle: v8::Global::new(scope, maybe.unwrap()),
165 })
166 }),
167 }
168 }
169
170 pub(crate) fn type_name(&self) -> &'static str {
171 match *self {
172 Value::Undefined => "undefined",
173 Value::Null => "null",
174 Value::Boolean(_) => "boolean",
175 Value::Number(_) => "number",
176 Value::Date(_) => "date",
177 Value::Function(_) => "function",
178 Value::Array(_) => "array",
179 Value::Object(_) => "object",
180 Value::String(_) => "string",
181 }
182 }
183
184 pub(crate) fn from_v8_value(
185 mv8: &MiniV8,
186 scope: &mut v8::HandleScope,
187 value: v8::Local<v8::Value>,
188 ) -> Value {
189 if value.is_undefined() {
190 Value::Undefined
191 } else if value.is_null() {
192 Value::Null
193 } else if value.is_boolean() {
194 Value::Boolean(value.boolean_value(scope))
195 } else if value.is_int32() {
196 Value::Number(value.int32_value(scope).unwrap() as f64)
197 } else if value.is_number() {
198 Value::Number(value.number_value(scope).unwrap())
199 } else if value.is_date() {
200 let value: v8::Local<v8::Date> = value.try_into().unwrap();
201 Value::Date(value.value_of())
202 } else if value.is_string() {
203 let value: v8::Local<v8::String> = value.try_into().unwrap();
204 let handle = v8::Global::new(scope, value);
205 Value::String(String { mv8: mv8.clone(), handle })
206 } else if value.is_array() {
207 let value: v8::Local<v8::Array> = value.try_into().unwrap();
208 let handle = v8::Global::new(scope, value);
209 Value::Array(Array { mv8: mv8.clone(), handle })
210 } else if value.is_function() {
211 let value: v8::Local<v8::Function> = value.try_into().unwrap();
212 let handle = v8::Global::new(scope, value);
213 Value::Function(Function { mv8: mv8.clone(), handle })
214 } else if value.is_object() {
215 let value: v8::Local<v8::Object> = value.try_into().unwrap();
216 let handle = v8::Global::new(scope, value);
217 Value::Object(Object { mv8: mv8.clone(), handle })
218 } else {
219 Value::Undefined
220 }
221 }
222
223 pub(crate) fn to_v8_value<'s>(&self, scope: &mut v8::HandleScope<'s>)
224 -> v8::Local<'s, v8::Value>
225 {
226 match self {
227 Value::Undefined => v8::undefined(scope).into(),
228 Value::Null => v8::null(scope).into(),
229 Value::Boolean(v) => v8::Boolean::new(scope, *v).into(),
230 Value::Number(v) => v8::Number::new(scope, *v).into(),
231 Value::Date(v) => v8::Date::new(scope, *v).unwrap().into(),
232 Value::Function(v) => v8::Local::new(scope, v.handle.clone()).into(),
233 Value::Array(v) => v8::Local::new(scope, v.handle.clone()).into(),
234 Value::Object(v) => v8::Local::new(scope, v.handle.clone()).into(),
235 Value::String(v) => v8::Local::new(scope, v.handle.clone()).into(),
236 }
237 }
238}
239
240impl fmt::Debug for Value {
241 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
242 match self {
243 Value::Undefined => write!(f, "undefined"),
244 Value::Null => write!(f, "null"),
245 Value::Boolean(b) => write!(f, "{:?}", b),
246 Value::Number(n) => write!(f, "{}", n),
247 Value::Date(d) => write!(f, "date:{}", d),
248 Value::String(s) => write!(f, "{:?}", s),
249 Value::Array(a) => write!(f, "{:?}", a),
250 Value::Function(u) => write!(f, "{:?}", u),
251 Value::Object(o) => write!(f, "{:?}", o),
252 }
253 }
254}
255
256pub trait ToValue {
258 fn to_value(self, mv8: &MiniV8) -> Result<Value>;
260}
261
262pub trait FromValue: Sized {
264 fn from_value(value: Value, mv8: &MiniV8) -> Result<Self>;
266}
267
268#[derive(Clone)]
270pub struct Values(Vec<Value>);
271
272impl Values {
273 pub fn new() -> Values {
275 Values(Vec::new())
276 }
277
278 pub fn from_vec(vec: Vec<Value>) -> Values {
279 Values(vec)
280 }
281
282 pub fn into_vec(self) -> Vec<Value> {
283 self.0
284 }
285
286 pub fn get(&self, index: usize) -> Value {
287 self.0.get(index).map(Clone::clone).unwrap_or(Value::Undefined)
288 }
289
290 pub fn from<T: FromValue>(&self, mv8: &MiniV8, index: usize) -> Result<T> {
291 T::from_value(self.0.get(index).map(Clone::clone).unwrap_or(Value::Undefined), mv8)
292 }
293
294 pub fn into<T: FromValues>(self, mv8: &MiniV8) -> Result<T> {
295 T::from_values(self, mv8)
296 }
297
298 pub fn len(&self) -> usize {
299 self.0.len()
300 }
301
302 pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a Value> {
303 self.0.iter()
304 }
305}
306
307impl FromIterator<Value> for Values {
308 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
309 Values::from_vec(Vec::from_iter(iter))
310 }
311}
312
313impl IntoIterator for Values {
314 type Item = Value;
315 type IntoIter = vec::IntoIter<Value>;
316
317 fn into_iter(self) -> Self::IntoIter {
318 self.0.into_iter()
319 }
320}
321
322impl<'a> IntoIterator for &'a Values {
323 type Item = &'a Value;
324 type IntoIter = slice::Iter<'a, Value>;
325
326 fn into_iter(self) -> Self::IntoIter {
327 (&self.0).into_iter()
328 }
329}
330
331pub trait ToValues {
336 fn to_values(self, mv8: &MiniV8) -> Result<Values>;
338}
339
340pub trait FromValues: Sized {
346 fn from_values(values: Values, mv8: &MiniV8) -> Result<Self>;
352}
353
354#[derive(Clone)]
361pub struct Variadic<T>(pub(crate) Vec<T>);
362
363impl<T> Variadic<T> {
364 pub fn new() -> Variadic<T> {
366 Variadic(Vec::new())
367 }
368
369 pub fn from_vec(vec: Vec<T>) -> Variadic<T> {
370 Variadic(vec)
371 }
372
373 pub fn into_vec(self) -> Vec<T> {
374 self.0
375 }
376}
377
378impl<T> FromIterator<T> for Variadic<T> {
379 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
380 Variadic(Vec::from_iter(iter))
381 }
382}
383
384impl<T> IntoIterator for Variadic<T> {
385 type Item = T;
386 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
387
388 fn into_iter(self) -> Self::IntoIter {
389 self.0.into_iter()
390 }
391}
392
393impl<T> Deref for Variadic<T> {
394 type Target = Vec<T>;
395
396 fn deref(&self) -> &Self::Target {
397 &self.0
398 }
399}
400
401impl<T> DerefMut for Variadic<T> {
402 fn deref_mut(&mut self) -> &mut Self::Target {
403 &mut self.0
404 }
405}