2020-02-04 02:22:44 +00:00
|
|
|
//! AVM2 values
|
|
|
|
|
2020-02-08 23:07:50 +00:00
|
|
|
use crate::avm2::names::Namespace;
|
2020-02-05 18:52:11 +00:00
|
|
|
use crate::avm2::object::Object;
|
2020-02-08 21:59:59 +00:00
|
|
|
use crate::avm2::Error;
|
2020-02-05 18:52:11 +00:00
|
|
|
use gc_arena::Collect;
|
2020-02-04 02:22:44 +00:00
|
|
|
|
|
|
|
/// An AVM2 value.
|
|
|
|
///
|
2020-02-05 18:52:11 +00:00
|
|
|
/// TODO: AVM2 also needs Scope, Namespace, and XML values.
|
|
|
|
#[derive(Clone, Collect, Debug)]
|
2020-02-04 02:22:44 +00:00
|
|
|
#[collect(no_drop)]
|
|
|
|
pub enum Value<'gc> {
|
|
|
|
Undefined,
|
|
|
|
Null,
|
2020-02-06 04:15:03 +00:00
|
|
|
Bool(bool),
|
2020-02-04 02:22:44 +00:00
|
|
|
Number(f64),
|
|
|
|
String(String),
|
2020-02-08 23:07:50 +00:00
|
|
|
Namespace(Namespace),
|
2020-02-05 18:52:11 +00:00
|
|
|
Object(Object<'gc>),
|
2020-02-04 02:22:44 +00:00
|
|
|
}
|
2020-02-06 04:15:03 +00:00
|
|
|
|
2020-02-07 00:28:54 +00:00
|
|
|
impl<'gc> From<String> for Value<'gc> {
|
|
|
|
fn from(string: String) -> Self {
|
|
|
|
Value::String(string)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<&str> for Value<'gc> {
|
|
|
|
fn from(string: &str) -> Self {
|
|
|
|
Value::String(string.to_owned())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<bool> for Value<'gc> {
|
|
|
|
fn from(value: bool) -> Self {
|
|
|
|
Value::Bool(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc, T> From<T> for Value<'gc>
|
|
|
|
where
|
|
|
|
Object<'gc>: From<T>,
|
|
|
|
{
|
|
|
|
fn from(value: T) -> Self {
|
|
|
|
Value::Object(Object::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<f64> for Value<'gc> {
|
|
|
|
fn from(value: f64) -> Self {
|
|
|
|
Value::Number(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<f32> for Value<'gc> {
|
|
|
|
fn from(value: f32) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<u8> for Value<'gc> {
|
|
|
|
fn from(value: u8) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<i16> for Value<'gc> {
|
|
|
|
fn from(value: i16) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<u16> for Value<'gc> {
|
|
|
|
fn from(value: u16) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<i32> for Value<'gc> {
|
|
|
|
fn from(value: i32) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<u32> for Value<'gc> {
|
|
|
|
fn from(value: u32) -> Self {
|
|
|
|
Value::Number(f64::from(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'gc> From<usize> for Value<'gc> {
|
|
|
|
fn from(value: usize) -> Self {
|
|
|
|
Value::Number(value as f64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-08 23:07:50 +00:00
|
|
|
impl<'gc> From<Namespace> for Value<'gc> {
|
|
|
|
fn from(value: Namespace) -> Self {
|
|
|
|
Value::Namespace(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-06 04:15:03 +00:00
|
|
|
impl PartialEq for Value<'_> {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Undefined => match other {
|
|
|
|
Value::Undefined => true,
|
|
|
|
_ => false,
|
|
|
|
},
|
|
|
|
Value::Null => match other {
|
|
|
|
Value::Null => true,
|
|
|
|
_ => false,
|
|
|
|
},
|
|
|
|
Value::Bool(value) => match other {
|
|
|
|
Value::Bool(other_value) => value == other_value,
|
|
|
|
_ => false,
|
|
|
|
},
|
|
|
|
Value::Number(value) => match other {
|
|
|
|
Value::Number(other_value) => {
|
|
|
|
(value == other_value) || (value.is_nan() && other_value.is_nan())
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
},
|
|
|
|
Value::String(value) => match other {
|
|
|
|
Value::String(other_value) => value == other_value,
|
|
|
|
_ => false,
|
|
|
|
},
|
|
|
|
Value::Object(value) => match other {
|
|
|
|
Value::Object(other_value) => Object::ptr_eq(*value, *other_value),
|
|
|
|
_ => false,
|
|
|
|
},
|
2020-02-08 23:07:50 +00:00
|
|
|
Value::Namespace(ns) => match other {
|
|
|
|
Value::Namespace(other_ns) => ns == other_ns,
|
|
|
|
_ => false,
|
|
|
|
},
|
2020-02-06 04:15:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-08 21:59:59 +00:00
|
|
|
|
|
|
|
impl<'gc> Value<'gc> {
|
|
|
|
pub fn as_object(&self) -> Result<Object<'gc>, Error> {
|
|
|
|
if let Value::Object(object) = self {
|
|
|
|
Ok(*object)
|
|
|
|
} else {
|
|
|
|
Err(format!("Expected Object, found {:?}", self).into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|