diff options
Diffstat (limited to 'bs5/universal/native/shared/JsMap.re')
-rw-r--r-- | bs5/universal/native/shared/JsMap.re | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/bs5/universal/native/shared/JsMap.re b/bs5/universal/native/shared/JsMap.re new file mode 100644 index 0000000..abf8cfc --- /dev/null +++ b/bs5/universal/native/shared/JsMap.re @@ -0,0 +1,76 @@ +[@platform js] +include { + type t('k, 'v); + + [@mel.new] external make: unit => t('k, 'v) = "Map"; + + [@mel.send] [@mel.return nullable] + external get: (t('k, 'v), 'k) => option('v) = "get"; + + [@mel.send] external set: (t('k, 'v), 'k, 'v) => unit = "set"; + + [@mel.send] external delete: (t('k, 'v), 'k) => unit = "delete"; + + [@mel.send] external clear: t('k, 'v) => unit = "clear"; + + [@mel.send] external size: t('k, 'v) => int = "size"; + + [@mel.send] external has: (t('k, 'v), 'k) => bool = "has"; + + [@mel.send] external values: t('k, 'v) => array('v) = "values"; + + [@mel.send] external keys: t('k, 'v) => array('k) = "keys"; + + [@mel.send] + external entries: t('k, 'v) => array(('k, 'v)) = "entries"; + + [@mel.send] + external forEach: (t('k, 'v), ('k, 'v) => unit) => unit = "forEach"; + }; + +[@platform native] +include { + type t('k, 'v) = {mutable entries: list(('k, 'v))}; + + let make = () => {entries: []}; + + let set = (map, k, v) => { + let rec update = entries => + switch (entries) { + | [] => [(k, v)] + | [(k', _), ...rest] when k == k' => [(k, v), ...rest] + | [pair, ...rest] => [pair, ...update(rest)] + }; + map.entries = update(map.entries); + map; + }; + + let get = (map, k) => + map.entries + |> List.find_opt(((k', _)) => k == k') + |> Option.map(((_, v)) => v); + + let delete = (map, k) => { + map.entries = List.filter(((k', _)) => k != k', map.entries); + map; + }; + + let clear = map => { + map.entries = []; + map; + }; + + let size = map => List.length(map.entries); + + let has = (map, k) => + List.exists(((k', _)) => k == k', map.entries); + + let values = map => List.map(((_, v)) => v, map.entries); + + let keys = map => List.map(((k, _)) => k, map.entries); + + let entries = map => map.entries; + + let forEach = (map, f) => + List.iter(((k, v)) => f(v, k, map), map.entries); + }; |