1import * as Pipeable from "../../Pipeable.ts"
2import type * as Schema from "../../Schema.ts"
3import * as SchemaAST from "../../SchemaAST.ts"
4import * as SchemaParser from "../../SchemaParser.ts"
5
6/** @internal */
7export const TypeId = "~effect/Schema/Schema"
8
9const RebuildOptions = Symbol()
10
11const SchemaProto = {
12 [TypeId]: TypeId,
13 get make() {
14 const value = SchemaParser.make(this as any)
15 Object.defineProperty(this, "make", { value, enumerable: true })
16 return value
17 },
18 get makeEffect() {
19 const value = SchemaParser.makeEffect(this as any)
20 Object.defineProperty(this, "makeEffect", { value, enumerable: true })
21 return value
22 },
23 get makeOption() {
24 const value = SchemaParser.makeOption(this as any)
25 Object.defineProperty(this, "makeOption", { value, enumerable: true })
26 return value
27 },
28 pipe() {
29 return Pipeable.pipeArguments(this, arguments)
30 },
31 annotate(this: Schema.Top, annotations: Schema.Annotations.Annotations) {
32 return this.rebuild(SchemaAST.annotate(this.ast, annotations))
33 },
34 annotateKey(this: Schema.Top, annotations: Schema.Annotations.Key<unknown>) {
35 return this.rebuild(SchemaAST.annotateKey(this.ast, annotations))
36 },
37 check(this: Schema.Top, ...checks: readonly [SchemaAST.Check<unknown>, ...Array<SchemaAST.Check<unknown>>]) {
38 return this.rebuild(SchemaAST.appendChecks(this.ast, checks))
39 },
40 rebuild(this: Schema.Top, ast: SchemaAST.AST) {
41 return make(ast, (this as any)[RebuildOptions])
42 }
43}
44
45/** @internal */
46export function make<S extends Schema.Constraint>(ast: S["ast"], options?: object): S {
47 function Schema() {}
48 const self = Object.setPrototypeOf(Schema, SchemaProto)
49 if (
50 options &&
51 (Object.hasOwn(options, "name") || Object.hasOwn(options, "length") || Object.hasOwn(options, "__proto__"))
52 ) {
53 Object.defineProperties(self, Object.getOwnPropertyDescriptors({ ...options }))
54 } else {
55 Object.assign(self, options)
56 }
57 self[RebuildOptions] = options
58 self.ast = ast
59 return self
60}