import { Box } from "./box"; import { DefaultOrFunc, getDefault } from "./fn"; import { isSome } from "./maybe"; import { Option } from "./option"; import { MapKey, MutableMapLike, MapValue, MapLike } from "./types"; /** Extended Map */ export function MapEx>(map: M) { return new ExMap(map) } /** Mutable Extended Map */ export function MutMapEx>(map: M) { return new MutableExMap(map) } /** Extended Map */ export class ExMap> implements Box, MapLike, MapValue> { constructor(public val: M) { } get(key: MapKey): MapValue | undefined { return this.val.get(key) } has(key: MapKey): boolean { return this.val.has(key) } /** If it does not exist, return to the default value */ getOrDefault(key: MapKey, defv: DefaultOrFunc>): MapValue { if (this.has(key)) { return this.get(key)! } else { return getDefault(defv) } } /** Get and pass to the callback */ getAndThen(key: MapKey, then: (val: MapValue) => any): void /** Get as Promise*/ getAndThen(key: MapKey): Promise> getAndThen(key: MapKey, then?: (val: MapValue) => any): void | Promise> { if (isSome(then)) { return new Promise(res => this.getAndThen(key, res)) } if (this.has(key)) { then!(this.get(key)!) } } /** Try to get * Option instead of Maybe to ensure that the value of None can be distinguished */ tryGet(key: MapKey): Option> { if (this.has(key)) { return Option.some(this.get(key)!) } else return Option.none() } } /** Mutable Extended Map */ export class MutableExMap> extends ExMap implements MutableMapLike, MapValue> { constructor(val: M) { super(val) } set(key: MapKey, value: MapValue): this { this.val.set(key, value) return this } delete(key: MapKey): boolean { return this.val.delete(key) } /** Get if has, add if not */ getOrAdd(key: MapKey, init: () => MapValue): MapValue { if (this.has(key)) { return this.get(key)! } else { const r = init() this.set(key, r) return r } } }