import { ParseConfig, createParser, typeDefProxy, UnknownTypeError, ValidationErrorMessage } from "./common.js" import { ArrowFunction } from "./arrowFunction.js" import { BuiltIn } from "./builtIn.js" import { List } from "./list.js" import { NumericStringLiteral } from "./numericStringLiteral.js" import { Or } from "./or.js" import { Resolution } from "./resolution.js" import { StringLiteral } from "./stringLiteral.js" import { Str } from "./str.js" export namespace Fragment { export type Definition = Def export type Validate< Def extends string, Root extends string, TypeSet > = Def extends Or.Definition ? Or.Validate<`${First}|${Second}`, Root, TypeSet> : Def extends ArrowFunction.Definition ? ArrowFunction.Validate : Def extends List.Definition ? Validate : Def extends | BuiltIn.Definition | StringLiteral.Definition | NumericStringLiteral.Definition ? Root : Def extends Resolution.Definition ? Resolution.Validate : UnknownTypeError export type Parse< Def extends string, TypeSet, Options extends ParseConfig > = Validate extends ValidationErrorMessage ? unknown : Def extends Resolution.Definition ? Resolution.Parse : Def extends Or.Definition ? Or.Parse : Def extends ArrowFunction.Definition ? ArrowFunction.Parse : Def extends List.Definition ? Parse[] : Def extends StringLiteral.Definition ? Literal : Def extends NumericStringLiteral.Definition ? // For now this is always inferred as 'number', even if the string is a literal like '5' Value : Def extends BuiltIn.Definition ? BuiltIn.Parse : unknown export const type = typeDefProxy as Definition export const parse = createParser({ type, parent: () => Str.parse, matches: (definition) => typeof definition === "string", children: () => [ Or.delegate, ArrowFunction.delegate, List.delegate, StringLiteral.delegate, NumericStringLiteral.delegate, BuiltIn.delegate, Resolution.delegate ] }) export const delegate = parse as any as Definition }