@@ -28,19 +28,87 @@ THE SOFTWARE.
2828
2929// deno-fmt-ignore-file
3030
31+ import { IsResult } from './internal/result.ts'
3132import { type TTrim , Trim } from './internal/trim.ts'
3233import { type TTake , Take } from './internal/take.ts'
33-
3434import { type TDigit , Digit } from './internal/char.ts'
35- import { type TZero , Zero } from './internal/char.ts'
35+ import { type THyphen , Hyphen } from './internal/char.ts'
36+ import { type TNonZero , NonZero } from './internal/char.ts'
37+ import { type TUnderScore , UnderScore } from './internal/char.ts'
3638
37- /** Matches if next is a BigInt literal with trailing `n` */
38- export type TInteger < Input extends string > = (
39- TTake < TTrim < Input > , [ ] >
39+ // ------------------------------------------------------------------
40+ // TakeSign
41+ // ------------------------------------------------------------------
42+ type TTakeSign < Input extends string > = (
43+ TTake < Input , [ THyphen ] > extends [ infer Sign extends string , infer Rest extends string ]
44+ ? [ Sign , Rest ]
45+ : [ '' , Input ]
46+ )
47+ function TakeSign < Input extends string > ( input : Input ) : TTakeSign < Input > {
48+ const result = Take ( input , [ Hyphen ] )
49+ return (
50+ IsResult ( result ) ? result : [ '' , input ]
51+ ) as never
52+ }
53+ // ------------------------------------------------------------------
54+ // TakeNonZero
55+ // ------------------------------------------------------------------
56+ type TTakeNonZero < Input extends string > = (
57+ TTake < Input , TNonZero >
58+ )
59+ function TakeNonZero < Input extends string > ( input : Input ) : TTakeNonZero < Input > {
60+ return Take ( input , NonZero )
61+ }
62+ // ------------------------------------------------------------------
63+ // TakeDigits
64+ // ------------------------------------------------------------------
65+ type TTakeDigits < Input extends string , Result extends string = '' > = (
66+ TTake < Input , TDigit > extends [ infer Digit extends string , infer Rest extends string ]
67+ ? TTakeDigits < Rest , `${Result } ${Digit } `>
68+ : [ Result , Input ]
69+ )
70+ function TakeDigits < Input extends string > ( input : Input , result : string = '' ) : TTakeDigits < Input > {
71+ const takeResult = Take ( input , Digit ) as [ string , string ]
72+ return (
73+ IsResult ( takeResult )
74+ ? TakeDigits ( takeResult [ 1 ] as never , `${ result } ${ takeResult [ 0 ] } ` )
75+ : [ result , input ]
76+ ) as never
77+ }
78+ // ------------------------------------------------------------------
79+ // TakeInteger
80+ // ------------------------------------------------------------------
81+ type TTakeInteger < Input extends string > = (
82+ TTakeSign < Input > extends [ infer Sign extends string , infer Rest extends string ]
83+ ? TTakeNonZero < Rest > extends [ infer NonZero extends string , infer Rest extends string ]
84+ ? TTakeDigits < Rest > extends [ infer Digits extends string , infer Rest extends string ]
85+ ? [ `${Sign } ${NonZero } ${Digits } `, Rest ]
86+ : [ ] // fail: did not match Digits
87+ : [ ] // fail: did not match NonZero
88+ : [ ] // fail: did not match Sign
4089)
41- /** Matches if next is a BigInt literal with trailing `n` */
90+ function TakeInteger < Input extends string > ( input : Input ) : TTakeInteger < Input > {
91+ const signResult = TakeSign ( input )
92+ return (
93+ IsResult ( signResult ) ? ( ( ) => {
94+ const nonZeroResult = TakeNonZero ( signResult [ 1 ] )
95+ return IsResult ( nonZeroResult ) ? ( ( ) => {
96+ const digitsResult = TakeDigits ( nonZeroResult [ 1 ] )
97+ return IsResult ( digitsResult )
98+ ? [ `${ signResult [ 0 ] } ${ nonZeroResult [ 0 ] } ${ digitsResult [ 0 ] } ` , digitsResult [ 1 ] ]
99+ : [ ] // fail: did not match Digits
100+ } ) ( ) : [ ] // fail: did not match NonZero
101+ } ) ( ) : [ ] // fail: did not match Sign
102+ ) as never
103+ }
104+ /** Matches if next is a Integer */
105+ export type TInteger < Input extends string ,
106+ Trimmed extends string = TTrim < Input >
107+ > = TTakeInteger < Trimmed >
108+ /** Matches if next is a Integer */
42109export function Integer < Input extends string >
43110 ( input : Input ) : TInteger < Input > {
44- return Take ( Trim ( input ) , [ ] ) as never
111+ const trimmed = Trim ( input )
112+ return TakeInteger ( trimmed ) as never
45113}
46114
0 commit comments