Files
bitburner-src/src/utils/Validator.ts
T
2023-10-23 04:49:12 -04:00

92 lines
2.9 KiB
TypeScript

export type ObjectValidator<T> = {
[key in keyof T]?: ParameterValidator<T, keyof T>;
};
interface ParameterValidatorObject<Type, Key extends keyof Type> {
default?: unknown;
min?: number;
max?: number;
func?: (obj: Type, validator: ObjectValidator<Type>, key: Key) => void;
}
type ParameterValidatorFunction<Type, Key extends keyof Type> = (obj: Type, key: Key) => void;
type ParameterValidator<Type, Key extends keyof Type> =
| ParameterValidatorObject<Type, Key>
| ParameterValidatorFunction<Type, Key>;
export function validateObject<Type extends Record<string, unknown>, Key extends keyof Type>(
obj: Type,
validator: ObjectValidator<Type>,
): void {
for (const key of Object.keys(validator) as Key[]) {
const paramValidator = validator[key];
if (paramValidator !== undefined) {
if (typeof paramValidator === "function") {
paramValidator(obj, key);
} else if (paramValidator.func !== undefined) {
paramValidator.func(obj, validator, key);
} else {
const objVal = obj[key];
if (typeof objVal !== typeof paramValidator.default) {
obj[key] = paramValidator.default as Type[Key];
}
if (typeof objVal === "number" && paramValidator.min !== undefined && objVal < paramValidator.min) {
obj[key] = paramValidator.min as Type[Key];
}
if (typeof objVal === "number" && paramValidator.max !== undefined && objVal > paramValidator.max) {
obj[key] = paramValidator.max as Type[Key];
}
}
}
}
}
export function minMax<Type, Key extends keyof Type>(
def: number,
min: number,
max: number,
): (obj: Type, key: Key & keyof Type) => void {
return (obj, key) => {
if (typeof obj[key] !== "number") {
obj[key] = def as unknown as Type[Key];
return;
}
if ((obj[key] as unknown as number) < min) {
obj[key] = min as unknown as Type[Key];
}
if ((obj[key] as unknown as number) > max) {
obj[key] = max as unknown as Type[Key];
}
};
}
export function oneOf<Type, Key extends keyof Type, Value>(
def: Value,
options: Value[],
): (obj: Type, key: Key & keyof Type) => void {
return (obj, key) => {
if (typeof obj[key] !== typeof def) {
obj[key] = def as unknown as Type[Key];
return;
}
if (!options.includes(obj[key] as unknown as Value)) {
obj[key] = def as unknown as Type[Key];
}
};
}
export function subsetOf<Type, Key extends keyof Type, Value>(
options: Value[],
): (obj: Type, key: Key & keyof Type) => void {
return (obj, key) => {
if (typeof obj[key] !== "object" || !Array.isArray(obj[key])) {
obj[key] = [] as unknown as Type[Key];
return;
}
const validValues: Value[] = [];
for (const value of obj[key] as unknown as Value[]) {
if (options.includes(value)) validValues.push(value);
}
obj[key] = validValues as unknown as Type[Key];
};
}