///|
/// A value that is neither null nor undefined
pub type Value
///|
pub(open) trait IsValue: IsAny {
as_value(Self) -> Value = _
}
///|
pub impl IsAny for Value
///|
pub impl IsValue for Value
///|
pub impl IsValue for Unit
///|
pub impl IsValue for Bool
///|
pub impl IsValue for Double
///|
pub impl IsValue for Int
///|
pub impl IsValue for String
///|
pub impl[T : IsValue] IsValue for Array[T]
///|
pub impl Show for Value with output(self, buf) {
buf.write_string(ffi_to_string(self))
}
///|
impl IsValue with as_value(self) {
identity(self)
}
///|
pub fn Value::as_any(self : Self) -> Any {
identity(self)
}
///|
pub fn Value::as_value(self : Self) -> Value {
identity(self)
}
///|
#callsite(autofill(loc))
pub fn Value::to_number(
self : Self,
loc~ : SourceLoc,
) -> Double raise InvalidCast {
if self.get_type() == "number" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Double")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_string(
self : Self,
loc~ : SourceLoc,
) -> String raise InvalidCast {
if self.get_type() is "string" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("String")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_object(
self : Self,
loc~ : SourceLoc,
) -> Object raise InvalidCast {
if self.get_type() == "object" && !ffi_object_is_null(self.as_any()) {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Object")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_error(
self : Self,
loc~ : SourceLoc,
) -> Error_ raise InvalidCast {
if self.instance_of("Error") {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Error")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_bigint(
self : Self,
loc~ : SourceLoc,
) -> Bigint raise InvalidCast {
if self.get_type() == "bigint" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Bigint")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_symbol(
self : Self,
loc~ : SourceLoc,
) -> Symbol raise InvalidCast {
if self.get_type() == "symbol" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Symbol")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_function(
self : Self,
loc~ : SourceLoc,
) -> Function raise InvalidCast {
if self.get_type() == "function" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Function")))
}
}
///|
#callsite(autofill(loc))
pub fn Value::to_boolean(
self : Self,
loc~ : SourceLoc,
) -> Bool raise InvalidCast {
if self.get_type() == "boolean" {
identity(self)
} else {
raise InvalidCast((loc, self.as_value(), Some("Bool")))
}
}
///|
#callsite(autofill(loc))
pub fn[T : DynCast] Value::to_array(
self : Self,
loc~ : SourceLoc,
) -> Array[T] raise {
if ffi_is_array(self) {
let arr : Array[Value] = identity(self)
arr.map(x => dyn_cast(x))
} else {
raise InvalidCast((loc, self.as_value(), Some("Array")))
}
}
///|
pub fn Value::get_type(self : Self) -> String {
ffi_typeof(self.as_any())
}
///|
pub fn Value::instance_of(
self : Self,
ctor : &IsStringOrFunctionOrObject,
) -> Bool {
let ctor = ctor.as_value()
let ctor = global_this.get_function(ctor.to_string()).as_value() catch {
InvalidCast(_) => ctor
_ => panic()
}
ffi_instanceof(self.as_any(), ctor)
}
///|
extern "js" fn ffi_typeof(x : Any) -> String = "(x) => typeof x"
///|
extern "js" fn ffi_instanceof(value : Any, ctor : Value) -> Bool = "(value, ctor) => value instanceof ctor"
///|
extern "js" fn ffi_to_string(x : Value) -> String = "(x) => JSON.stringify(x)"
///|
extern "js" fn ffi_is_array(x : Value) -> Bool = "(x) => Array.isArray(x)"
///|
fn[A, B] identity(a : A) -> B = "%identity"