import { type Money } from "./money_amount_types.ts";
// Money is declared in function.fune: integer minor units, never a float.
const CURRENCY = /^[A-Z]{3}$/;
export function money(minor: number, currency: string): Money {
if (!Number.isInteger(minor)) {
throw new TypeError(`money() takes integer minor units, received ${minor}`);
}
if (typeof currency !== "string" || !CURRENCY.test(currency)) {
throw new RangeError(`"${currency}" is not an uppercase ISO 4217 currency code`);
}
return { minor, currency };
}
export function isMoney(value: unknown): value is Money {
return (
typeof value === "object" &&
value !== null &&
Number.isInteger((value as Money).minor) &&
CURRENCY.test((value as Money).currency ?? "")
);
}
/** Guard against the silent nonsense of adding GBP to EUR. */
export function assertSameCurrency(a: Money, b: Money): void {
if (a.currency !== b.currency) {
throw new RangeError(`currency mismatch: ${a.currency} and ${b.currency}`);
}
}
export function zero(currency: string): Money {
return money(0, currency);
}