import { Schema as S } from "@effect/schema" import { Simplify } from "type-fest" import { Trait, TraitTuple } from "../Trait" import { TraitExpression } from "../TraitExpression" import { TraitExpressionBuilder } from "../TraitExpressionBuilder" import { spreadSupertraits } from "../spreadSupertraits" import { traitsUnique } from "../traitsUnique" import { Extendable, StaticMembers } from "../util" import { EffectSchemaTraitExpression } from "./EffectSchemaTraitExpression" export class EffectSchemaInitialTraitExpressionBuilder { class< Fields extends S.Struct.Fields >( identifier: string, fields: Fields, annotations?: S.Annotations.Schema, ) { return new EffectSchemaTraitExpressionBuilder( S.Class(identifier)(fields, annotations), {}, [], "Immutable", "Immutable", ) } taggedClass< Tag extends string, Fields extends S.Struct.Fields, >( tag: Tag, fields: Fields, annotations?: S.Annotations.Schema, ) { return new EffectSchemaTraitExpressionBuilder( S.TaggedClass()(tag, fields, annotations), {}, [], "Immutable", "Immutable", ) } extends< Super extends StaticMembers>, Self extends object, Fields extends S.Struct.Fields, I, R, C, Inherited extends object, Proto, NewFields extends S.Struct.Fields, >( superclass: Super | StaticMembers>, identifier: string, fields: NewFields, annotations?: S.Annotations.Schema, ) { return new EffectSchemaTraitExpressionBuilder( superclass.extend(identifier)(fields, annotations), {} as Simplify< Omit > >, [], "Immutable", "Immutable", ) } } export class EffectSchemaTraitExpressionBuilder< Fields extends S.Struct.Fields, I, R, C, Inherited extends object, Proto, Static extends object, const Traits extends readonly Trait[], const Mutability extends "Immutable" | "Mutable", const EncodedMutability extends "Immutable" | "Mutable", > { constructor( readonly expressionSuperclass: S.Class, readonly expressionSuperclassStatic: Static, readonly expressionTraits: Traits, readonly expressionMutability: Mutability, readonly expressionEncodedMutability: EncodedMutability, ) {} mutable() { return new EffectSchemaTraitExpressionBuilder( this.expressionSuperclass, this.expressionSuperclassStatic, this.expressionTraits, "Mutable", this.expressionEncodedMutability, ) } immutable() { return new EffectSchemaTraitExpressionBuilder( this.expressionSuperclass, this.expressionSuperclassStatic, this.expressionTraits, "Immutable", this.expressionEncodedMutability, ) } mutableEncoded() { return new EffectSchemaTraitExpressionBuilder( this.expressionSuperclass, this.expressionSuperclassStatic, this.expressionTraits, this.expressionMutability, "Mutable", ) } immutableEncoded() { return new EffectSchemaTraitExpressionBuilder( this.expressionSuperclass, this.expressionSuperclassStatic, this.expressionTraits, this.expressionMutability, "Immutable", ) } expresses< const T extends readonly Trait< TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] >, any, any, any >[] >( ...traits: T ) { return new EffectSchemaTraitExpressionBuilder( this.expressionSuperclass, this.expressionSuperclassStatic, traitsUnique([ ...this.expressionTraits, ...spreadSupertraits(traits), ]) as TraitExpressionBuilder.ExpressesReturnTypeTraits, this.expressionMutability, this.expressionEncodedMutability, ) } build(): ( Extendable> extends false ? "Type conflict between the traits abstract definitions." : Extendable> extends false ? "Type conflict between the traits static abstract definitions." : Extendable<[ InstanceType, ...TraitTuple.MapImplInstance, ]> extends false ? "Type conflict between the traits implementation instance and/or the superclass instance." : Extendable<[ Static, ...TraitTuple.MapImplStaticMembers, ]> extends false ? "Type conflict between the traits implementation static members and/or the superclass static members." : EffectSchemaTraitExpression< Fields, I, R, C, Inherited, Proto, Static, Traits, Mutability, EncodedMutability > ) { return new EffectSchemaTraitExpression( this.expressionSuperclass, this.expressionSuperclassStatic, this.expressionTraits, this.expressionMutability, this.expressionEncodedMutability, ) as any } } export const effectSchemaExpression = new EffectSchemaInitialTraitExpressionBuilder()