import { Type } from "../type.ts";import { Any, isNegativeZero } from "../utils.ts";
function isHexCode(c: number): boolean { return ( (0x30 <= c && c <= 0x39) || (0x41 <= c && c <= 0x46) || (0x61 <= c && c <= 0x66) );}
function isOctCode(c: number): boolean { return 0x30 <= c && c <= 0x37 ;}
function isDecCode(c: number): boolean { return 0x30 <= c && c <= 0x39 ;}
function resolveYamlInteger(data: string): boolean { const max = data.length; let index = 0; let hasDigits = false;
if (!max) return false;
let ch = data[index];
if (ch === "-" || ch === "+") { ch = data[++index]; }
if (ch === "0") { if (index + 1 === max) return true; ch = data[++index];
if (ch === "b") { index++;
for (; index < max; index++) { ch = data[index]; if (ch === "_") continue; if (ch !== "0" && ch !== "1") return false; hasDigits = true; } return hasDigits && ch !== "_"; }
if (ch === "x") { index++;
for (; index < max; index++) { ch = data[index]; if (ch === "_") continue; if (!isHexCode(data.charCodeAt(index))) return false; hasDigits = true; } return hasDigits && ch !== "_"; }
for (; index < max; index++) { ch = data[index]; if (ch === "_") continue; if (!isOctCode(data.charCodeAt(index))) return false; hasDigits = true; } return hasDigits && ch !== "_"; }
if (ch === "_") return false;
for (; index < max; index++) { ch = data[index]; if (ch === "_") continue; if (ch === ":") break; if (!isDecCode(data.charCodeAt(index))) { return false; } hasDigits = true; }
if (!hasDigits || ch === "_") return false;
if (ch !== ":") return true;
return /^(:[0-5]?[0-9])+$/.test(data.slice(index));}
function constructYamlInteger(data: string): number { let value = data; const digits: number[] = [];
if (value.indexOf("_") !== -1) { value = value.replace(/_/g, ""); }
let sign = 1; let ch = value[0]; if (ch === "-" || ch === "+") { if (ch === "-") sign = -1; value = value.slice(1); ch = value[0]; }
if (value === "0") return 0;
if (ch === "0") { if (value[1] === "b") return sign * parseInt(value.slice(2), 2); if (value[1] === "x") return sign * parseInt(value, 16); return sign * parseInt(value, 8); }
if (value.indexOf(":") !== -1) { value.split(":").forEach((v): void => { digits.unshift(parseInt(v, 10)); });
let valueInt = 0; let base = 1;
digits.forEach((d): void => { valueInt += d * base; base *= 60; });
return sign * valueInt; }
return sign * parseInt(value, 10);}
function isInteger(object: Any): boolean { return ( Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !isNegativeZero(object) );}
export const int = new Type("tag:yaml.org,2002:int", { construct: constructYamlInteger, defaultStyle: "decimal", kind: "scalar", predicate: isInteger, represent: { binary(obj: number): string { return obj >= 0 ? `0b${obj.toString(2)}` : `-0b${obj.toString(2).slice(1)}`; }, octal(obj: number): string { return obj >= 0 ? `0${obj.toString(8)}` : `-0${obj.toString(8).slice(1)}`; }, decimal(obj: number): string { return obj.toString(10); }, hexadecimal(obj: number): string { return obj >= 0 ? `0x${obj.toString(16).toUpperCase()}` : `-0x${obj.toString(16).toUpperCase().slice(1)}`; }, }, resolve: resolveYamlInteger, styleAliases: { binary: [2, "bin"], decimal: [10, "dec"], hexadecimal: [16, "hex"], octal: [8, "oct"], },});