import type { Literal, ParseOptions, TemplateLiteral, TypeLiteral } from "../AST.js";
import type { Brand, Validation } from "@fncts/base/data/Branded";
import { show } from "@fncts/base/data/Showable";
import { getParameter } from "../AST.js";
import { ASTTag, concrete, TemplateLiteralSpan } from "../AST.js";
import { ownKeys } from "../utils.js";
/**
* @tsplus static fncts.schema.SchemaOps fromAST
*/
export function make(ast: AST): Schema {
return new Schema(ast);
}
/**
* @tsplus pipeable fncts.schema.Schema annotate
*/
export function annotate(annotation: ASTAnnotation, value: V) {
return (self: Schema): Schema => {
return Schema.fromAST(self.ast.clone({ annotations: self.ast.annotations.annotate(annotation, value) }));
};
}
/**
* @tsplus static fncts.schema.SchemaOps declaration
*/
export function declaration(
typeParameters: Vector>,
decode: (...typeParameters: ReadonlyArray>) => Parser,
encode: (...typeParameters: ReadonlyArray>) => Parser,
annotations?: ASTAnnotationMap,
): Schema {
return Schema.fromAST(
AST.createDeclaration(
typeParameters.map((tp) => tp.ast),
(...typeParameters) => decode(...typeParameters.map(Schema.fromAST)),
(...typeParameters) => encode(...typeParameters.map(Schema.fromAST)),
annotations,
),
);
}
/**
* @tsplus pipeable fncts.schema.Schema filter
*/
export function filter(refinement: Refinement): (self: Schema) => Schema;
export function filter(predicate: Predicate): (self: Schema) => Schema;
export function filter(predicate: Predicate) {
return (self: Schema): Schema => {
const ast: AST = AST.createRefinement(self.ast, predicate);
return Schema.fromAST(ast);
};
}
/**
* @tsplus pipeable fncts.schema.Schema brand
*/
export function brand(validation: Validation) {
return (self: Schema): Schema> => {
const ast = AST.createRefinement(
self.ast,
validation.validate,
self.ast.annotations.annotate(ASTAnnotation.Brand, Vector(validation)),
);
return Schema.fromAST(ast);
};
}
function makeLiteral(value: Literal): Schema {
return Schema.fromAST(AST.createLiteral(value));
}
/**
* @tsplus static fncts.schema.SchemaOps literal
*/
export function literal>(...literals: Literals): Schema {
return Schema.union(...literals.map(makeLiteral));
}
/**
* @tsplus static fncts.schema.SchemaOps never
* @tsplus implicit
*/
export const never: Schema = Schema.fromAST(AST.neverKeyword);
/**
* @tsplus static fncts.schema.SchemaOps unknown
* @tsplus implicit
*/
export const unknown: Schema = Schema.fromAST(AST.unknownKeyword);
/**
* @tsplus static fncts.schema.SchemaOps any
*/
export const any: Schema = Schema.fromAST(AST.anyKeyword);
/**
* @tsplus static fncts.schema.SchemaOps undefined
* @tsplus implicit
*/
export const _undefined: Schema = Schema.fromAST(AST.undefinedKeyword);
export { _undefined as undefined };
/**
* @tsplus static fncts.schema.SchemaOps null
* @tsplus implicit
*/
export const _null: Schema = Schema.fromAST(AST.createLiteral(null));
export { _null as null };
/**
* @tsplus static fncts.schema.SchemaOps void
* @tsplus implicit
*/
export const _void: Schema = Schema.fromAST(AST.voidKeyword);
export { _void as void };
/**
* @tsplus static fncts.schema.SchemaOps string
* @tsplus implicit
*/
export const string: Schema = Schema.fromAST(AST.stringKeyword);
/**
* @tsplus static fncts.schema.SchemaOps number
* @tsplus implicit
*/
export const number: Schema = Schema.fromAST(AST.numberKeyword);
/**
* @tsplus static fncts.schema.SchemaOps boolean
* @tsplus implicit
*/
export const boolean: Schema = Schema.fromAST(AST.booleanKeyword);
/**
* @tsplus static fncts.schema.SchemaOps bigint
* @tsplus implicit
*/
export const bigint: Schema = Schema.fromAST(AST.bigIntKeyword);
/**
* @tsplus static fncts.schema.SchemaOps symbol
* @tsplus implicit
*/
export const symbol: Schema = Schema.fromAST(AST.symbolKeyword);
/**
* @tsplus static fncts.schema.SchemaOps object
* @tsplus implicit
*/
export const object: Schema