import { stringFormat } from "@decaf-ts/decorator-validation";
import { OverflowError } from "./errors";
import { ValidationError } from "@decaf-ts/db-decorators";
/**
* @description Overflow-safe addition operation
* @summary Adds two numbers and verifies no overflow by reverse-checking the operands
* @param {number} a - First operand
* @param {number} b - Second operand
* @return {number} The sum of a and b
* @function add
* @throws {OverflowError} on addition overflow
* @memberOf module:for-fabric.shared
*/
export function add(a: number, b: number): number {
const c = a + b;
if (a !== c - b || b !== c - a) {
throw new OverflowError(`Addition overflow: ${a} + ${b}`);
}
return c;
}
/**
* @description Overflow-safe subtraction operation
* @summary Subtracts b from a and validates no overflow by reverse-checking the operands
* @param {number} a - Minuend
* @param {number} b - Subtrahend
* @return {number} The difference a - b
* @function sub
* @throws {OverflowError} on subtaction overflow
* @memberOf module:for-fabric.shared
*/
export function sub(a: number, b: number): number {
const c = a - b;
if (a !== c + b || b !== a - c) {
throw new OverflowError(`Subtraction overflow: ${a} - ${b}`);
}
return c;
}
/**
* @summary Safe Integer Parse
*
* @param {string} string
*
* @function safeParseInt
*
* @throws {ValidationError} if parseInt returns NaN
*
* @memberOf module:for-fabric.shared
*/
export function safeParseInt(string: string): number {
// Regular expression to check if string only have digits
const digitRegex = /^\d+$/;
if (!digitRegex.test(string)) {
throw new ValidationError(
stringFormat("Failed to parse: {0}", "string contains digits")
);
}
const parsedint = parseInt(string);
if (isNaN(parsedint)) {
throw new ValidationError(
stringFormat("Failed to parse: {0}", "string is not a parsable integer")
);
}
return parsedint;
}
Source