Hyperlinkv0.8.0-beta.28

BigDecimal

BigDecimal.fromStringconsteffect/BigDecimal.ts:1378
(s: string): Option.Option<BigDecimal>

Parses a decimal string into a BigDecimal safely.

When to use

Use to parse external decimal text without throwing on invalid input.

Details

Returns Option.some for valid decimal or exponent notation and Option.none when the string cannot be parsed or would produce an unsafe scale. The empty string parses as zero.

Example (Parsing decimal strings safely)

import { BigDecimal, Option } from "effect"
import * as assert from "node:assert"

assert.deepStrictEqual(BigDecimal.fromString("123"), Option.some(BigDecimal.make(123n, 0)))
assert.deepStrictEqual(
  BigDecimal.fromString("123.456"),
  Option.some(BigDecimal.make(123456n, 3))
)
assert.deepStrictEqual(BigDecimal.fromString("123.abc"), Option.none())
export const fromString = (s: string): Option.Option<BigDecimal> => {
  if (s === "") {
    return Option.some(zero)
  }

  let base: string
  let exp: number
  const seperator = s.search(/[eE]/)
  if (seperator !== -1) {
    const trail = s.slice(seperator + 1)
    base = s.slice(0, seperator)
    exp = Number(trail)
    if (base === "" || !Number.isSafeInteger(exp) || !FINITE_INT_REGEXP.test(trail)) {
      return Option.none()
    }
  } else {
    base = s
    exp = 0
  }

  let digits: string
  let offset: number
  const dot = base.search(/\./)
  if (dot !== -1) {
    const lead = base.slice(0, dot)
    const trail = base.slice(dot + 1)
    digits = `${lead}${trail}`
    offset = trail.length
  } else {
    digits = base
    offset = 0
  }

  if (!FINITE_INT_REGEXP.test(digits)) {
    return Option.none()
  }

  const scale = offset - exp
  if (!Number.isSafeInteger(scale)) {
    return Option.none()
  }

  return Option.some(make(BigInt(digits), scale))
}
Referenced by 3 symbols