deno.land / std@0.224.0 / yaml / _type / float.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126// Ported from js-yaml v3.13.1:// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { type StyleVariant, Type } from "../type.ts";import { type Any, isNegativeZero } from "../_utils.ts";
const YAML_FLOAT_PATTERN = new RegExp( // 2.5e4, 2.5 and integers "^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?" + // .2e4, .2 // special case, seems not from spec "|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?" + // 20:59 "|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*" + // .inf "|[-+]?\\.(?:inf|Inf|INF)" + // .nan "|\\.(?:nan|NaN|NAN))$",);
function resolveYamlFloat(data: string): boolean { if ( !YAML_FLOAT_PATTERN.test(data) || // Quick hack to not allow integers end with `_` // Probably should update regexp & check speed data[data.length - 1] === "_" ) { return false; }
return true;}
function constructYamlFloat(data: string): number { let value = data.replace(/_/g, "").toLowerCase(); const sign = value[0] === "-" ? -1 : 1; const digits: number[] = [];
if (value[0] && "+-".indexOf(value[0]) >= 0) { value = value.slice(1); }
if (value === ".inf") { return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; } if (value === ".nan") { return NaN; } if (value.indexOf(":") >= 0) { value.split(":").forEach((v) => { digits.unshift(parseFloat(v)); });
let valueNb = 0.0; let base = 1;
digits.forEach((d) => { valueNb += d * base; base *= 60; });
return sign * valueNb; } return sign * parseFloat(value);}
const SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
function representYamlFloat(object: Any, style?: StyleVariant): Any { if (isNaN(object)) { switch (style) { case "lowercase": return ".nan"; case "uppercase": return ".NAN"; case "camelcase": return ".NaN"; } } else if (Number.POSITIVE_INFINITY === object) { switch (style) { case "lowercase": return ".inf"; case "uppercase": return ".INF"; case "camelcase": return ".Inf"; } } else if (Number.NEGATIVE_INFINITY === object) { switch (style) { case "lowercase": return "-.inf"; case "uppercase": return "-.INF"; case "camelcase": return "-.Inf"; } } else if (isNegativeZero(object)) { return "-0.0"; }
const res = object.toString(10);
// JS stringifier can build scientific format without dots: 5e-100, // while YAML requires dot: 5.e-100. Fix it with simple hack
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;}
function isFloat(object: Any): boolean { return ( Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || isNegativeZero(object)) );}
export const float = new Type("tag:yaml.org,2002:float", { construct: constructYamlFloat, defaultStyle: "lowercase", kind: "scalar", predicate: isFloat, represent: representYamlFloat, resolve: resolveYamlFloat,});
Version Info