UNPKG

@sschepis/resolang

Version:

ResoLang - Core quantum resonance computation library

391 lines (350 loc) 10.4 kB
/** * Validation utility functions for common validation patterns * Consolidates validation logic across the codebase */ import { ValidationException } from "./errors"; import { Prime } from "../types"; /** * Validates that a value is not null */ export function requireNonNull<T>(value: T | null, paramName: string): T { if (value === null) { throw new ValidationException(`${paramName} cannot be null`); } return value; } /** * Validates that a number is positive */ export function requirePositive(value: f64, paramName: string): f64 { if (value <= 0) { throw new ValidationException(`${paramName} must be positive, got ${value}`); } return value; } /** * Validates that a number is non-negative */ export function requireNonNegative(value: f64, paramName: string): f64 { if (value < 0) { throw new ValidationException(`${paramName} must be non-negative, got ${value}`); } return value; } /** * Validates that an integer is positive */ export function requirePositiveInt(value: i32, paramName: string): i32 { if (value <= 0) { throw new ValidationException(`${paramName} must be a positive integer, got ${value}`); } return value; } /** * Validates that an integer is non-negative */ export function requireNonNegativeInt(value: i32, paramName: string): i32 { if (value < 0) { throw new ValidationException(`${paramName} must be a non-negative integer, got ${value}`); } return value; } /** * Validates that a value is within a range (inclusive) */ export function requireInRange(value: f64, min: f64, max: f64, paramName: string): f64 { if (value < min || value > max) { throw new ValidationException(`${paramName} must be between ${min} and ${max}, got ${value}`); } return value; } /** * Validates that an integer is within a range (inclusive) */ export function requireInRangeInt(value: i32, min: i32, max: i32, paramName: string): i32 { if (value < min || value > max) { throw new ValidationException(`${paramName} must be between ${min} and ${max}, got ${value}`); } return value; } /** * Validates that a string is not empty */ export function requireNonEmpty(value: string, paramName: string): string { if (value.length === 0) { throw new ValidationException(`${paramName} cannot be empty`); } return value; } /** * Validates that an array is not empty */ export function requireNonEmptyArray<T>(value: Array<T>, paramName: string): Array<T> { if (value.length === 0) { throw new ValidationException(`${paramName} cannot be an empty array`); } return value; } /** * Validates that an array has a specific length */ export function requireArrayLength<T>(value: Array<T>, expectedLength: i32, paramName: string): Array<T> { if (value.length !== expectedLength) { throw new ValidationException(`${paramName} must have length ${expectedLength}, got ${value.length}`); } return value; } /** * Validates that an array has a minimum length */ export function requireMinArrayLength<T>(value: Array<T>, minLength: i32, paramName: string): Array<T> { if (value.length < minLength) { throw new ValidationException(`${paramName} must have at least ${minLength} elements, got ${value.length}`); } return value; } /** * Validates that a value is a valid probability (0-1) */ export function requireProbability(value: f64, paramName: string): f64 { if (value < 0.0 || value > 1.0) { throw new ValidationException(`${paramName} must be a probability between 0 and 1, got ${value}`); } return value; } /** * Validates that a value is a valid phase angle (0-2π) */ export function requirePhase(value: f64, paramName: string): f64 { if (value < 0.0 || value >= 2.0 * Math.PI) { throw new ValidationException(`${paramName} must be a phase between 0 and 2π, got ${value}`); } return value; } /** * Validates that a value is a valid normalized value (0-1) */ export function requireNormalized(value: f64, paramName: string): f64 { return requireProbability(value, paramName); } /** * Validates that a prime number is valid */ export function requireValidPrime(value: Prime, paramName: string): Prime { if (value < 2) { throw new ValidationException(`${paramName} must be a prime number >= 2, got ${value}`); } return value; } /** * Validates that all elements in an array are unique */ export function requireUniqueElements<T>(value: Array<T>, paramName: string): Array<T> { const seen = new Set<T>(); for (let i = 0; i < value.length; i++) { if (seen.has(value[i])) { throw new ValidationException(`${paramName} contains duplicate element: ${value[i]}`); } seen.add(value[i]); } return value; } /** * Validates that a Map is not empty */ export function requireNonEmptyMap<K, V>(value: Map<K, V>, paramName: string): Map<K, V> { if (value.size === 0) { throw new ValidationException(`${paramName} cannot be an empty map`); } return value; } /** * Validates that a Set is not empty */ export function requireNonEmptySet<T>(value: Set<T>, paramName: string): Set<T> { if (value.size === 0) { throw new ValidationException(`${paramName} cannot be an empty set`); } return value; } /** * Validates that a buffer has a specific size */ export function requireBufferSize(value: Uint8Array, expectedSize: i32, paramName: string): Uint8Array { if (value.length !== expectedSize) { throw new ValidationException(`${paramName} must have size ${expectedSize}, got ${value.length}`); } return value; } /** * Validates that a buffer has a minimum size */ export function requireMinBufferSize(value: Uint8Array, minSize: i32, paramName: string): Uint8Array { if (value.length < minSize) { throw new ValidationException(`${paramName} must have at least ${minSize} bytes, got ${value.length}`); } return value; } /** * Validates that two values are equal */ export function requireEqual<T>(actual: T, expected: T, message: string): T { if (actual !== expected) { throw new ValidationException(`${message}: expected ${expected}, got ${actual}`); } return actual; } /** * Validates that two values are not equal */ export function requireNotEqual<T>(actual: T, notExpected: T, message: string): T { if (actual === notExpected) { throw new ValidationException(`${message}: value must not be ${notExpected}`); } return actual; } /** * Validates that a condition is true */ export function requireTrue(condition: bool, message: string): void { if (!condition) { throw new ValidationException(message); } } /** * Validates that a condition is false */ export function requireFalse(condition: bool, message: string): void { if (condition) { throw new ValidationException(message); } } /** * Validates that a string matches a pattern (simple contains check) */ export function requireContains(value: string, substring: string, paramName: string): string { if (!value.includes(substring)) { throw new ValidationException(`${paramName} must contain "${substring}"`); } return value; } /** * Validates that a string starts with a prefix */ export function requireStartsWith(value: string, prefix: string, paramName: string): string { if (!value.startsWith(prefix)) { throw new ValidationException(`${paramName} must start with "${prefix}"`); } return value; } /** * Validates that a string ends with a suffix */ export function requireEndsWith(value: string, suffix: string, paramName: string): string { if (!value.endsWith(suffix)) { throw new ValidationException(`${paramName} must end with "${suffix}"`); } return value; } /** * Validates that a value is one of the allowed values */ export function requireOneOf<T>(value: T, allowedValues: Array<T>, paramName: string): T { for (let i = 0; i < allowedValues.length; i++) { if (value === allowedValues[i]) { return value; } } throw new ValidationException(`${paramName} must be one of: ${allowedValues.join(", ")}, got ${value}`); } /** * Validates that a value is not one of the forbidden values */ export function requireNotOneOf<T>(value: T, forbiddenValues: Array<T>, paramName: string): T { for (let i = 0; i < forbiddenValues.length; i++) { if (value === forbiddenValues[i]) { throw new ValidationException(`${paramName} must not be ${value}`); } } return value; } /** * Validates that a value passes a custom predicate */ export function requirePredicate<T>(value: T, predicate: (v: T) => bool, paramName: string, message: string): T { if (!predicate(value)) { throw new ValidationException(`${paramName}: ${message}`); } return value; } /** * Validates multiple conditions and returns all validation errors */ export class ValidationBuilder { private errors: Array<string>; constructor() { this.errors = new Array<string>(); } /** * Adds a validation check */ check(condition: bool, message: string): ValidationBuilder { if (!condition) { this.errors.push(message); } return this; } /** * Adds a validation for non-null */ checkNonNull<T>(value: T | null, paramName: string): ValidationBuilder { if (value === null) { this.errors.push(`${paramName} cannot be null`); } return this; } /** * Adds a validation for positive number */ checkPositive(value: f64, paramName: string): ValidationBuilder { if (value <= 0) { this.errors.push(`${paramName} must be positive, got ${value}`); } return this; } /** * Adds a validation for range */ checkInRange(value: f64, min: f64, max: f64, paramName: string): ValidationBuilder { if (value < min || value > max) { this.errors.push(`${paramName} must be between ${min} and ${max}, got ${value}`); } return this; } /** * Returns true if all validations passed */ isValid(): bool { return this.errors.length === 0; } /** * Gets all validation errors */ getErrors(): Array<string> { return this.errors; } /** * Throws if any validation failed */ validate(): void { if (this.errors.length > 0) { throw new ValidationException(`Validation failed:\n${this.errors.join("\n")}`); } } } /** * Creates a new validation builder */ export function validate(): ValidationBuilder { return new ValidationBuilder(); }