UNPKG

@hazae41/box

Version:

Rust-like Box and similar objects for TypeScript

163 lines (160 loc) 4.09 kB
import { BorrowedError } from '../borrow/index.mjs'; import { Deferred } from '../deferred/index.mjs'; import { MovedError } from '../move/index.mjs'; import { Ref } from '../ref/index.mjs'; /** * A movable and borrowable reference */ class Box { value; clean; #state = "owned"; /** * An movable and borrowable reference * @param value */ constructor(value, clean) { this.value = value; this.clean = clean; } static wrap(value) { return new Box(value, value); } static from(value) { return new Box(value.get(), value); } static with(value, clean) { return new Box(value, new Deferred(() => clean(value))); } [Symbol.dispose]() { if (this.moved) return; this.clean[Symbol.dispose](); } async [Symbol.asyncDispose]() { this[Symbol.dispose](); } get owned() { return this.#state === "owned"; } get borrowed() { return this.#state === "borrowed"; } get moved() { return this.#state === "moved"; } /** * Get the value * @returns T */ get() { return this.value; } /** * Get the value or null-like if not owned * @returns T or null-like if not owned */ getOrNull() { if (this.borrowed) return; if (this.moved) return; return this.value; } /** * Get the value or throw if not owned * @returns T * @throws NotOwnedError if not owned */ getOrThrow() { if (this.borrowed) throw new BorrowedError(); if (this.moved) throw new MovedError(); return this.value; } checkOrNull() { if (this.borrowed) return; if (this.moved) return; return this; } checkOrThrow() { if (this.borrowed) throw new BorrowedError(); if (this.moved) throw new MovedError(); return this; } /** * Get the value and set this as moved or null-like if not owned * @returns T or null-like if not owned */ unwrapOrNull() { if (this.borrowed) return; if (this.moved) return; this.#state = "moved"; return this.value; } /** * Get the value and set this as moved or throw if not owned * @returns T * @throws BoxMovedError if not owned */ unwrapOrThrow() { if (this.borrowed) throw new BorrowedError(); if (this.moved) throw new MovedError(); this.#state = "moved"; return this.value; } /** * Move the value to a new box and set this one as moved or null-like if already moved * @returns Box<T> or null-like if moved */ moveOrNull() { if (this.borrowed) return; if (this.moved) return; this.#state = "moved"; return new Box(this.value, this.clean); } /** * Move the value to a new box and set this one as moved or throw if already moved * @returns Box<T> * @throws BoxMovedError if already moved */ moveOrThrow() { if (this.borrowed) throw new BorrowedError(); if (this.moved) throw new MovedError(); this.#state = "moved"; return new Box(this.value, this.clean); } borrowOrNull() { if (this.borrowed) return; if (this.moved) return; this.#state = "borrowed"; const dispose = () => { this.#state = "owned"; }; return new Ref(this.value, new Deferred(dispose)); } borrowOrThrow() { if (this.borrowed) throw new BorrowedError(); if (this.moved) throw new MovedError(); this.#state = "borrowed"; const dispose = () => { this.#state = "owned"; }; return new Ref(this.value, new Deferred(dispose)); } } export { Box }; //# sourceMappingURL=index.mjs.map