Skip to content

Commit

Permalink
feat: allow trailing zeros & only specifying decimal component when u…
Browse files Browse the repository at this point in the history
…sing string.numeric.parse (#1220)
  • Loading branch information
TizzySaurus authored Dec 4, 2024
1 parent a5f7e4b commit 3ac3fd8
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ark/type/__tests__/defaults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ contextualize(() => {
const defaulted = type({ a }).default(() => ({}))

attest(defaulted.expression).snap(
'{ a?: (In: string /^(?!^-0$)-?(?:0|[1-9]\\d*)(?:\\.\\d*[1-9])?$/) => Out<number> = "1" }'
'{ a?: (In: string /^(?:(?:(?!^-0(\\.0+)?$)-?(?:0|[1-9]\\d*)(?:\\.\\d+)?)|-?(?:\\.\\d+))$/) => Out<number> = "1" }'
)
attest(defaulted).type.toString.snap(`Type<
of<
Expand Down
2 changes: 1 addition & 1 deletion ark/type/__tests__/pipe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ contextualize(() => {
>`)

attest(t.expression).snap(
"{ l: 1, n: (In: string /^(?!^-0$)-?(?:0|[1-9]\\d*)(?:\\.\\d*[1-9])?$/) => Out<number> } | { n: (In: string /^(?!^-0$)-?(?:0|[1-9]\\d*)(?:\\.\\d*[1-9])?$/) => Out<number>, r: 1 }"
"{ l: 1, n: (In: string /^(?:(?:(?!^-0(\\.0+)?$)-?(?:0|[1-9]\\d*)(?:\\.\\d+)?)|-?(?:\\.\\d+))$/) => Out<number> } | { n: (In: string /^(?:(?:(?!^-0(\\.0+)?$)-?(?:0|[1-9]\\d*)(?:\\.\\d+)?)|-?(?:\\.\\d+))$/) => Out<number>, r: 1 }"
)
attest(t({ l: 1, n: "234" })).snap({ l: 1, n: 234 })
attest(t({ r: 1, n: "234" })).snap({ r: 1, n: 234 })
Expand Down
4 changes: 2 additions & 2 deletions ark/type/keywords/string/numeric.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { intrinsic, rootSchema } from "@ark/schema"
import { wellFormedNumberMatcher } from "@ark/util"
import { numericStringMatcher } from "@ark/util"
import type { Nominal, of, To } from "../../attributes.ts"
import type { Module, Submodule } from "../../module.ts"
import { arkModule } from "../utils.ts"
Expand All @@ -10,7 +10,7 @@ declare namespace string {
}

const root = regexStringNode(
wellFormedNumberMatcher,
numericStringMatcher,
"a well-formed numeric string"
)

Expand Down
12 changes: 12 additions & 0 deletions ark/util/numbers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { throwParseError } from "./errors.ts"
import { anchoredRegex } from "./strings.ts"

export type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Expand Down Expand Up @@ -34,6 +35,17 @@ export const wellFormedNumberMatcher: RegExp =
export const isWellFormedNumber: RegExp["test"] =
wellFormedNumberMatcher.test.bind(wellFormedNumberMatcher)

/**
* Matches a well-formatted numeric expression according to the following rules:
* 1. The first digit of the value must not be 0, unless the entire integer portion is 0
* 2. The value may not be "-0"
*/
const integerMatcher = /(?!^-0(\.0+)?$)-?(?:0|[1-9]\d*)/
const decimalMatcher = /(?:\.\d+)/
export const numericStringMatcher: RegExp = anchoredRegex(
`(?:${integerMatcher.source}${decimalMatcher.source}?)|-?${decimalMatcher.source}`
)

export const numberLikeMatcher = /^-?\d*\.?\d*$/
const isNumberLike = (s: string) => s.length !== 0 && numberLikeMatcher.test(s)

Expand Down

0 comments on commit 3ac3fd8

Please sign in to comment.