export type LoadingStateType = "unset" | "loading" | "loaded" | "error";

export class LoadingState<T> {
    state: LoadingStateType;

    errorMessage?: string;

    value?: T;

    constructor(props: { state?: LoadingStateType, errorMessage?: string, value?: T }) {
        this.state = props.state ? props.state : "unset";
        this.errorMessage = props.errorMessage;
        this.value = props.value;
    }

    public static Unset<T>() {
        return new LoadingState<T>({ state: "unset" });
    }

    public static Loading<T>() {
        return new LoadingState<T>({ state: "loading" });
    }

    public static Error<T>(props: { errorMessage: string }) {
        const { errorMessage } = props;
        return new LoadingState<T>({ state: "error", errorMessage });
    }

    public static Loaded<T>(props: { value?: T }) {
        const { value } = props;
        return new LoadingState<T>({ state: "loaded", value });
    }

    public isUnset() : boolean {
        return this.state === "unset";
    }
    public isLoading() : boolean {
        return this.state === "loading";
    }
    public isError() : boolean {
        return this.state === "error";
    }
    public isLoaded() : boolean {
        return this.state === "loaded";
    }
}