// JavaScript Map and Set collections
//
// These types use "Js" prefix to avoid conflicts with MoonBit's builtin Map and Set types.
///| JsMap
///|
/// JavaScript Map
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
#external
pub type JsMap[K, V]
///|
pub fn[K, V] JsMap::to_any(self : JsMap[K, V]) -> @core.Any = "%identity"
///|
/// JS: new Map()
pub fn[K, V] JsMap::new() -> JsMap[K, V] {
ffi_new_map() |> @core.identity
}
///|
extern "js" fn ffi_new_map() -> @core.Any =
#| () => new Map()
///|
/// JS: new Map(entries)
pub fn[K, V] JsMap::from_entries(entries : Array[(K, V)]) -> JsMap[K, V] {
let map : JsMap[K, V] = JsMap::new()
for entry in entries {
let (k, v) = entry
map.set(k, v) |> ignore
}
map
}
///|
/// JS: map.set(key, value)
pub fn[K, V] JsMap::set(self : JsMap[K, V], key : K, value : V) -> JsMap[K, V] {
self.to_any()._call("set", [@core.any(key), @core.any(value)]).cast()
}
///|
/// JS: map._get(key)
pub fn[K, V] JsMap::get(self : JsMap[K, V], key : K) -> V? {
let result = self.to_any()._call("get", [@core.any(key)])
if @core.is_undefined(result.cast()) {
None
} else {
Some(result.cast())
}
}
///|
#alias("_[_]")
pub fn[K, V] JsMap::_get(self : JsMap[K, V], key : K) -> V? {
self.get(key)
}
///|
/// JS: map.has(key)
pub fn[K, V] JsMap::has(self : JsMap[K, V], key : K) -> Bool {
self.to_any()._call("has", [@core.any(key)]).cast()
}
///|
/// JS: map.delete(key)
pub fn[K, V] JsMap::delete(self : JsMap[K, V], key : K) -> Bool {
self.to_any()._call("delete", [@core.any(key)]).cast()
}
///|
/// JS: map.clear()
pub fn[K, V] JsMap::clear(self : JsMap[K, V]) -> Unit {
self.to_any()._call("clear", []) |> ignore
}
///|
/// JS: map.size
pub fn[K, V] JsMap::size(self : JsMap[K, V]) -> Int {
self.to_any()["size"].cast()
}
///|
/// JS: map.keys()
pub fn[K, V] JsMap::keys(self : JsMap[K, V]) -> @iterator.JsIterator[K] {
self.to_any()._call("keys", []).cast()
}
///|
/// JS: map.values()
pub fn[K, V] JsMap::values(self : JsMap[K, V]) -> @iterator.JsIterator[V] {
self.to_any()._call("values", []).cast()
}
///|
/// JS: map.entries()
pub fn[K, V] JsMap::entries(self : JsMap[K, V]) -> @iterator.JsIterator[(K, V)] {
self.to_any()._call("entries", []).cast()
}
///|
/// JS: map.forEach(callback)
pub fn[K, V] JsMap::forEach(
self : JsMap[K, V],
callback : (V, K) -> Unit,
) -> Unit {
self.to_any()._call("forEach", [@core.any(callback)]) |> ignore
}
///| JsSet
///|
/// JavaScript Set
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
#external
pub type JsSet[T]
///|
pub fn[T] JsSet::to_any(self : JsSet[T]) -> @core.Any = "%identity"
///|
/// JS: new Set()
pub fn[T] JsSet::new() -> JsSet[T] {
ffi_new_set() |> @core.identity
}
///|
extern "js" fn ffi_new_set() -> @core.Any =
#| () => new Set()
///|
/// JS: new Set(values)
pub fn[T] JsSet::from_array(values : Array[T]) -> JsSet[T] {
let set : JsSet[T] = JsSet::new()
for value in values {
set.add(value) |> ignore
}
set
}
///|
/// JS: set.add(value)
pub fn[T] JsSet::add(self : JsSet[T], value : T) -> JsSet[T] {
self.to_any()._call("add", [@core.any(value)]).cast()
}
///|
/// JS: set.has(value)
pub fn[T] JsSet::has(self : JsSet[T], value : T) -> Bool {
self.to_any()._call("has", [@core.any(value)]).cast()
}
///|
/// JS: set.delete(value)
pub fn[T] JsSet::delete(self : JsSet[T], value : T) -> Bool {
self.to_any()._call("delete", [@core.any(value)]).cast()
}
///|
/// JS: set.clear()
pub fn[T] JsSet::clear(self : JsSet[T]) -> Unit {
self.to_any()._call("clear", []) |> ignore
}
///|
/// JS: set.size
pub fn[T] JsSet::size(self : JsSet[T]) -> Int {
self.to_any()["size"].cast()
}
///|
/// JS: set.values()
pub fn[T] JsSet::values(self : JsSet[T]) -> @iterator.JsIterator[T] {
self.to_any()._call("values", []).cast()
}
///|
/// JS: set.keys() - Same as values() for Set
pub fn[T] JsSet::keys(self : JsSet[T]) -> @iterator.JsIterator[T] {
self.to_any()._call("keys", []).cast()
}
///|
/// JS: set.entries() - Returns [value, value] pairs for compatibility
pub fn[T] JsSet::entries(self : JsSet[T]) -> @iterator.JsIterator[(T, T)] {
self.to_any()._call("entries", []).cast()
}
///|
/// JS: set.forEach(callback)
pub fn[T] JsSet::forEach(self : JsSet[T], callback : (T) -> Unit) -> Unit {
self.to_any()._call("forEach", [@core.any(callback)]) |> ignore
}