//·························································· // Copyright (c) 2023-2026. Jonathan Bédard ~ JóôòKiwi // // This project is free to use. // All the right is reserved to the author of this project. // My projects: // - https://github.com/joooKiwi/type // - https://github.com/joooKiwi/lazy // - https://github.com/joooKiwi/collection // - https://github.com/joooKiwi/enumeration //·························································· import type {Lazy} from "@joookiwi/lazy" import type {Nullable} from "@joookiwi/type" import {lazy} from "@joookiwi/lazy" import type {Enumerable} from "./Enumerable" import type {EnumerableWithParent} from "./EnumerableWithParent" import type {NameOf, PossibleNameOf} from "./type/nameOf" import type {PossibleOrdinalOf} from "./type/ordinalOf" import type {PossibleEnumerableValueOrNameByValueOrCallback} from "./type/possibleInstance" import {Enum} from "./Enum" import {EnumConstants} from "./EnumConstants" import {KnownEnumConstructors} from "./KnownEnumConstructors" import {NullReferenceException} from "./exception/NullReferenceException" import {_getParentValueFromName} from "./method/_getParentValueFromName" /** * An {@link Enum} class in conjuncture with the {@link EnumerableWithParent}. * * Compared to its sibling {@link EnumWithNullableParent}, it does not want `null`. * * It can throw a {@link NullReferenceException} in different scenarios: * - A `null` is received during the construction * - A `null` is interpreted on the {@link EnumWithParent.parent parent} * - An exception is thrown when attempting to retrieve its {@link CompanionEnumWithParent} * - An exception is thrown when attempting to retrieve the value by {@link CompanionEnumWithParentDeclaration.getValue getValue()} * * @see EnumWithNullableParent */ export abstract class EnumWithParent = PossibleOrdinalOf, const NAME extends PossibleNameOf = PossibleNameOf, > extends Enum implements EnumerableWithParent { //#region -------------------- Fields -------------------- readonly #parent: Lazy static { KnownEnumConstructors.add(EnumWithParent,) } //#endregion -------------------- Fields -------------------- //#region -------------------- Constructor -------------------- /** * Create the instance with a {@link EnumerableWithParent.parent parent} reference * having the same {@link Enum.name name} as the current instance */ protected constructor() /** * Create the instance with a {@link EnumerableWithParent.parent parent} reference. * * @param parent The parent reference */ protected constructor(parent: Nullable,) /** * Create the instance with a {@link EnumerableWithParent.parent parent} {@link Enumerable.name name} reference * * @param parentName The parent reference retrieved from the {@link Enumerable.name name} value */ protected constructor(parentName: Nullable>,) /** * Create the instance with a {@link EnumerableWithParent.parent parent} reference * via a callback * * @param lateParent The late parent reference */ protected constructor(lateParent: Nullable<() => Nullable>,) /** * Create the instance with a {@link EnumerableWithParent.parent parent} {@link Enumerable.name name} reference * via a callback * * @param lateParentName The late parent reference retrieved from its {@link Enumerable.name name} value */ protected constructor(lateParentName: Nullable<() => Nullable>>,) /** * Create the instance with a parent from any possible values (in Javascript) * * @param parent The parent value (from any possibilities in Javascript) * * @typescriptDefinition */ protected constructor(parent?: PossibleEnumerableValueOrNameByValueOrCallback,) protected constructor(parent?: PossibleEnumerableValueOrNameByValueOrCallback,) { super() if (arguments.length === 0) { // We default to the name of the instance this.#parent = lazy(() => _getParentValueFromName(this, this.name,),) return } if (parent instanceof Function) parent = parent() this.#parent = lazy(() => { if (parent == null) throw new NullReferenceException(`The parent received on the “${this.constructor.name}” cannot be null on an Enumerable with non-null value.`, parent,) if (typeof parent == "string") return _getParentValueFromName(this, parent,) if (parent === EnumConstants.ENUM_REFERENCE_BY_ITS_NAME_SYMBOL) return _getParentValueFromName(this, this.name,) if (parent === EnumConstants.NULL_ENUM_REFERENCE_SYMBOL) throw new NullReferenceException(`The parent received on the “${this.constructor.name}” cannot be null on an Enumerable with non-null value.`, parent,) if (parent instanceof String) return _getParentValueFromName(this, parent.valueOf(),) return parent },) } //#endregion -------------------- Constructor -------------------- //#region -------------------- Getter methods -------------------- /** * The parent of the current instance * * @lazy * @throws NullReferenceException An error happened while attempting to retrieve the parent value */ public get parent(): PARENT { return this.#parent.value } //#endregion -------------------- Getter methods -------------------- }