///|
/// A `Value` can be undefined.
///
/// This value is not boxed, which means `Optional::some(Optional::undefined())`
/// is the same as `Optional::undefined()`.
type Optional[T]
///|
pub impl[T] IsAny for Optional[T]
///|
#callsite(autofill(loc))
pub fn[T] Optional::unwrap(
self : Self[T],
loc~ : SourceLoc,
) -> T raise UnwrapUndefined {
if ffi_is_undefined(identity(self)) {
raise UnwrapUndefined(loc)
} else {
identity(self)
}
}
///|
#callsite(autofill(loc))
pub fn Optional::unwrap_value(
self : Self[Nullable[Value]],
loc~ : SourceLoc,
) -> Value raise {
self.unwrap(loc~).unwrap(loc~)
}
///|
pub fn[T] Optional::from(x : T) -> Optional[T] {
identity(x)
}
///|
pub fn[T] Optional::undefined() -> Optional[T] {
identity(ffi_undefined())
}
///|
pub fn[T] Optional::to_option(self : Self[T]) -> T? {
if ffi_is_undefined(identity(self)) {
None
} else {
Some(identity(self))
}
}
///|
pub fn[T] Optional::from_option(opt : T?) -> Self[T] {
match opt {
None => undefined()
Some(x) => identity(x)
}
}
///|
pub fnalias Optional::(from as optional, undefined)
///|
extern "js" fn ffi_is_undefined(x : Any) -> Bool = "(x) => x === undefined"
///|
extern "js" fn ffi_undefined() -> Any = "() => undefined"