/* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ import {isNumber, IValidator, ValidationResult} from "./index"; type NumberRule = | { type: "equal", value: number } | { type: "notEqual", value: number } export class NumberValidator implements IValidator { constructor(private rules?: NumberRule[]) { if (!Array.isArray(this.rules)) { this.rules = []; } } /** * Adds a rule to the array of rules, or replaces a rule if it already exists. * Use this function to prevent having multiple rules of the same type. */ private addRule: (rule: NumberRule) => NumberRule[] = rule => { // Filter the current rule set, removing any rule that has the same type of the one being added const filtered = this.rules.filter(r => r.type !== rule.type); // Add the new rule to the filtered rule array return [...filtered, rule] } /** * Fails if the value being validated is not equal to @param value. */ equals: (value: number) => NumberValidator = value => { this.rules = this.addRule({ type: "equal", value: value }); return this; } /** * Fails if the value being validated is equal to @param value. */ notEquals: (value: number) => NumberValidator = value => { this.rules = this.addRule({ type: "notEqual", value: value }); return this; } /** * Checks an individual rule against the value being validated. */ checkRule: (rule: NumberRule, value: number) => ValidationResult = (rule: NumberRule, value : number) => { const err = (msg: string) : ValidationResult => ({ success: false, message: msg }); const ok = () : ValidationResult => ({ success: true, value: value }); switch (rule.type) { case "equal": return rule.value !== value ? err(`Value was expected to be ${rule.value} but was ${value}.`) : ok(); case "notEqual": return rule.value === value ? err(`Value must not be ${rule.value}.`) : ok(); } } go: (value: unknown) => ValidationResult = value => { if (!isNumber(value)) { return { success: false, message: `Expected a number but received ${typeof value}.` } } for (let rule of this.rules) { const result = this.checkRule(rule, value); if (result.success === false) { return result; } } // If none of the rules in the loop had an error, the value passed validation! return { success: true, value: value } } }