Skip to content

Commit 8414966

Browse files
committed
feat: parse File size bounds in the type string parser
1 parent 755ecf0 commit 8414966

4 files changed

Lines changed: 38 additions & 10 deletions

File tree

ark/type/attributes.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
type optionalKeyOf,
1313
type Primitive,
1414
type show,
15+
type SizeLiteral,
1516
type unionKeyOf,
1617
type unionToTuple
1718
} from "@ark/util"
@@ -28,7 +29,9 @@ export type DateLiteral<source extends string = string> =
2829
| `d"${source}"`
2930
| `d'${source}'`
3031

31-
export type LimitLiteral = number | DateLiteral
32+
export type { SizeLiteral } from "@ark/util"
33+
34+
export type LimitLiteral = number | DateLiteral | SizeLiteral
3235

3336
export type normalizeLimit<limit> =
3437
limit extends DateLiteral<infer source> ? source

ark/type/parser/ast/bounds.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { writeUnboundableMessage } from "@ark/schema"
22
import type { ErrorMessage, array, typeToString } from "@ark/util"
3-
import type { InferredMorph, LimitLiteral } from "../../attributes.ts"
3+
import type {
4+
InferredMorph,
5+
LimitLiteral,
6+
SizeLiteral
7+
} from "../../attributes.ts"
48
import type { Comparator } from "../reduce/shared.ts"
59
import type {
610
BoundExpressionKind,
@@ -32,6 +36,11 @@ export type validateBound<
3236
: [bounded] extends [Date] ?
3337
// allow numeric or date literal as a Date limit
3438
validateAst<boundedAst, $, args>
39+
: [bounded] extends [File] ?
40+
// allow numeric or size literal as a File limit, but not a date literal
41+
[limit] extends [number | SizeLiteral] ?
42+
validateAst<boundedAst, $, args>
43+
: ErrorMessage<writeInvalidLimitMessage<comparator, limit, boundKind>>
3544
: [bounded] extends [InferredMorph] ?
3645
ErrorMessage<writeConstrainedMorphMessage<boundedAst>>
3746
: ErrorMessage<writeUnboundableMessage<typeToString<bounded>>>

ark/type/parser/shift/operand/unenclosed.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
import {
1313
printable,
1414
throwParseError,
15+
tryParseSizeLiteral,
1516
tryParseWellFormedBigint,
1617
tryParseWellFormedNumber,
1718
type BigintLiteral,
@@ -20,6 +21,7 @@ import {
2021
type join,
2122
type lastOf
2223
} from "@ark/util"
24+
import type { SizeLiteral } from "../../../attributes.ts"
2325
import type { ArkAmbient } from "../../../config.ts"
2426
import type { resolutionToAst } from "../../../scope.ts"
2527
import type { GenericInstantiationAst } from "../../ast/generic.ts"
@@ -144,6 +146,9 @@ const maybeParseUnenclosedLiteral = (
144146
const maybeBigint = tryParseWellFormedBigint(token)
145147
if (maybeBigint !== undefined)
146148
return s.ctx.$.node("unit", { unit: maybeBigint })
149+
150+
const maybeSize = tryParseSizeLiteral(token)
151+
if (maybeSize !== undefined) return s.ctx.$.node("unit", { unit: maybeSize })
147152
}
148153

149154
type tryResolve<
@@ -192,6 +197,8 @@ type tryResolve<
192197
>
193198
: token extends BigintLiteral<infer b> ?
194199
s.setRoot<s, InferredAst<b, token>, unscanned>
200+
: token extends SizeLiteral ?
201+
s.setRoot<s, InferredAst<number, token>, unscanned>
195202
: token extends "keyof" ? s.addPrefix<s, "keyof", unscanned>
196203
: unresolvableState<s, token, $, args, []>
197204

ark/type/parser/shift/operator/bounds.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type NodeSchema
77
} from "@ark/schema"
88
import { isKeyOf, throwParseError, type KeySet, type Scanner } from "@ark/util"
9-
import type { DateLiteral } from "../../../attributes.ts"
9+
import type { DateLiteral, LimitLiteral } from "../../../attributes.ts"
1010
import type { InferredAst } from "../../ast/infer.ts"
1111
import type { astToString } from "../../ast/utils.ts"
1212
import type { RootedRuntimeState, RuntimeState } from "../../reduce/dynamic.ts"
@@ -60,10 +60,7 @@ export type parseBound<
6060
>
6161
) ?
6262
s["root"] extends (
63-
InferredAst<
64-
Date | number,
65-
`${infer limit extends number | DateLiteral}`
66-
>
63+
InferredAst<Date | number, `${infer limit extends LimitLiteral}`>
6764
) ?
6865
s.reduceLeftBound<s, limit, comparator, nextUnscanned>
6966
: parseRightBound<s.scanTo<s, nextUnscanned>, comparator, $, args>
@@ -103,7 +100,7 @@ export const writeIncompatibleRangeMessage = (
103100

104101
export const getBoundKinds = (
105102
comparator: Comparator,
106-
limit: number | DateLiteral,
103+
limit: LimitLiteral,
107104
root: BaseRoot,
108105
boundKind: BoundExpressionKind
109106
): BoundKind[] => {
@@ -140,6 +137,18 @@ export const getBoundKinds = (
140137
: ["before"]
141138
)
142139
}
140+
if (root.extends($ark.intrinsic.File)) {
141+
if (typeof limit !== "number") {
142+
return throwParseError(
143+
writeInvalidLimitMessage(comparator, limit, boundKind)
144+
)
145+
}
146+
return (
147+
comparator === "==" ? ["minSize", "maxSize"]
148+
: comparator[0] === ">" ? ["minSize"]
149+
: ["maxSize"]
150+
)
151+
}
143152
return throwParseError(writeUnboundableMessage(root.expression))
144153
}
145154

@@ -181,7 +190,7 @@ export const parseRightBound = (
181190

182191
const boundKinds = getBoundKinds(
183192
comparator,
184-
typeof limit === "number" ? limit : (limitToken as DateLiteral),
193+
limit instanceof Date ? (limitToken as DateLiteral) : limit,
185194
previousRoot,
186195
"right"
187196
)
@@ -217,7 +226,7 @@ export type parseRightBound<
217226
> =
218227
parseOperand<s, $, args> extends infer nextState extends StaticState ?
219228
nextState["root"] extends (
220-
InferredAst<unknown, `${infer limit extends number | DateLiteral}`>
229+
InferredAst<unknown, `${infer limit extends LimitLiteral}`>
221230
) ?
222231
s["branches"]["leftBound"] extends {} ?
223232
comparator extends MaxComparator ?

0 commit comments

Comments
 (0)