EffectSchemaTraitExpressionBuilder
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { unique } from "remeda"
|
||||
import { AbstractClass, IsEqual } from "type-fest"
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { Trait, TraitTuple } from "./Trait"
|
||||
import { TraitExpression } from "./TraitExpression"
|
||||
import { SpreadSupertraits, spreadSupertraits } from "./spreadSupertraits"
|
||||
import { TraitsUnique, traitsUnique } from "./traitsUnique"
|
||||
import { Extendable, StaticMembers } from "./util"
|
||||
|
||||
|
||||
@@ -9,56 +10,18 @@ export class TraitExpressionBuilder<
|
||||
Superclass extends AbstractClass<object>,
|
||||
const Traits extends readonly Trait<any, any, any, any>[],
|
||||
> {
|
||||
declare ["constructor"]: typeof TraitExpressionBuilder
|
||||
|
||||
constructor(
|
||||
readonly expressionSuperclass: Superclass,
|
||||
readonly expressionTraits: Traits,
|
||||
) {}
|
||||
|
||||
|
||||
static spreadSupertraits<
|
||||
const T extends readonly Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
readonly Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return traits.flatMap(trait => [
|
||||
...trait.superExpression.traits,
|
||||
trait,
|
||||
]) as readonly Trait<any, any, any, any>[] as TraitExpressionBuilder.SpreadSupertraits<T>
|
||||
}
|
||||
|
||||
static traitsUnique<
|
||||
const T extends readonly Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
readonly Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return unique(traits) as readonly Trait<any, any, any, any>[] as TraitExpressionBuilder.TraitsUnique<T>
|
||||
}
|
||||
|
||||
|
||||
extends<
|
||||
Super extends AbstractClass<object>
|
||||
>(
|
||||
superclass: Super
|
||||
) {
|
||||
return new this.constructor(
|
||||
return new TraitExpressionBuilder(
|
||||
superclass,
|
||||
this.expressionTraits,
|
||||
)
|
||||
@@ -80,12 +43,12 @@ export class TraitExpressionBuilder<
|
||||
Superclass,
|
||||
TraitExpressionBuilder.ExpressesReturnTypeTraits<Traits, T>
|
||||
> {
|
||||
return new this.constructor(
|
||||
return new TraitExpressionBuilder(
|
||||
this.expressionSuperclass,
|
||||
|
||||
this.constructor.traitsUnique([
|
||||
traitsUnique([
|
||||
...this.expressionTraits,
|
||||
...this.constructor.spreadSupertraits(traits),
|
||||
...spreadSupertraits(traits),
|
||||
]),
|
||||
)
|
||||
}
|
||||
@@ -106,11 +69,11 @@ export class TraitExpressionBuilder<
|
||||
Superclass,
|
||||
TraitExpressionBuilder.ExpressesFirstReturnTypeTraits<Traits, T>
|
||||
> {
|
||||
return new this.constructor(
|
||||
return new TraitExpressionBuilder(
|
||||
this.expressionSuperclass,
|
||||
|
||||
this.constructor.traitsUnique([
|
||||
...this.constructor.spreadSupertraits(traits),
|
||||
traitsUnique([
|
||||
...spreadSupertraits(traits),
|
||||
...this.expressionTraits,
|
||||
]),
|
||||
)
|
||||
@@ -141,44 +104,13 @@ export class TraitExpressionBuilder<
|
||||
}
|
||||
|
||||
export namespace TraitExpressionBuilder {
|
||||
export type SpreadSupertraits<Traits> = (
|
||||
Traits extends readonly [
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
...infer Rest,
|
||||
]
|
||||
? readonly [
|
||||
...Trait.Supertraits<El>,
|
||||
El,
|
||||
...SpreadSupertraits<Rest>,
|
||||
]
|
||||
: readonly []
|
||||
)
|
||||
|
||||
export type TraitsUnique<Traits> = (
|
||||
Traits extends readonly [
|
||||
...infer Rest,
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
]
|
||||
? IsTraitInTupleFromRight<Rest, El> extends true
|
||||
? TraitsUnique<Rest>
|
||||
: readonly [...TraitsUnique<Rest>, El]
|
||||
: readonly []
|
||||
)
|
||||
type IsTraitInTupleFromRight<Traits, T> = (
|
||||
Traits extends readonly [...infer Rest, infer El]
|
||||
? IsEqual<El, T> extends true
|
||||
? true
|
||||
: IsTraitInTupleFromRight<Rest, T>
|
||||
: false
|
||||
)
|
||||
|
||||
export type ExpressesReturnTypeTraits<
|
||||
Traits extends readonly Trait<any, any, any, any>[],
|
||||
T extends readonly Trait<any, any, any, any>[],
|
||||
> = (
|
||||
TraitExpressionBuilder.TraitsUnique<readonly [
|
||||
TraitsUnique<readonly [
|
||||
...Traits,
|
||||
...TraitExpressionBuilder.SpreadSupertraits<T>,
|
||||
...SpreadSupertraits<T>,
|
||||
]>
|
||||
)
|
||||
|
||||
@@ -186,8 +118,8 @@ export namespace TraitExpressionBuilder {
|
||||
Traits extends readonly Trait<any, any, any, any>[],
|
||||
T extends readonly Trait<any, any, any, any>[],
|
||||
> = (
|
||||
TraitExpressionBuilder.TraitsUnique<readonly [
|
||||
...TraitExpressionBuilder.SpreadSupertraits<T>,
|
||||
TraitsUnique<readonly [
|
||||
...SpreadSupertraits<T>,
|
||||
...Traits,
|
||||
]>
|
||||
)
|
||||
|
||||
78
src/effect/EffectSchemaTraitExpressionBuilder.ts
Normal file
78
src/effect/EffectSchemaTraitExpressionBuilder.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Schema as S } from "@effect/schema"
|
||||
import { Trait } from "../Trait"
|
||||
import { TraitExpression } from "../TraitExpression"
|
||||
import { TraitExpressionBuilder } from "../TraitExpressionBuilder"
|
||||
import { spreadSupertraits } from "../spreadSupertraits"
|
||||
import { traitsUnique } from "../traitsUnique"
|
||||
|
||||
|
||||
export class EffectSchemaTraitExpressionBuilder<
|
||||
Superclass extends S.Class<unknown, Fields, A, I, R, C, Inherited, Proto>,
|
||||
const Traits extends readonly Trait<any, any, any, any>[],
|
||||
|
||||
Fields extends S.Struct.Fields,
|
||||
A, I, R, C,
|
||||
Inherited extends object,
|
||||
Proto,
|
||||
> {
|
||||
constructor(
|
||||
readonly expressionSuperclass: Superclass,
|
||||
readonly expressionTraits: Traits,
|
||||
) {}
|
||||
|
||||
|
||||
extends<
|
||||
Super extends S.Class<unknown, SuperFields, SuperA, SuperI, SuperR, SuperC, SuperInherited, SuperProto>,
|
||||
|
||||
SuperFields extends S.Struct.Fields,
|
||||
SuperA, SuperI, SuperR, SuperC,
|
||||
SuperInherited extends object,
|
||||
SuperProto,
|
||||
>(
|
||||
superclass: Super | S.Class<unknown, SuperFields, SuperA, SuperI, SuperR, SuperC, SuperInherited, SuperProto>
|
||||
) {
|
||||
return new EffectSchemaTraitExpressionBuilder<
|
||||
Super,
|
||||
Traits,
|
||||
|
||||
SuperFields,
|
||||
SuperA, SuperI, SuperR, SuperC,
|
||||
SuperInherited,
|
||||
SuperProto
|
||||
>(
|
||||
superclass as Super,
|
||||
this.expressionTraits,
|
||||
)
|
||||
}
|
||||
|
||||
expresses<
|
||||
const T extends readonly Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
readonly Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
...traits: T
|
||||
): EffectSchemaTraitExpressionBuilder<
|
||||
Superclass,
|
||||
TraitExpressionBuilder.ExpressesReturnTypeTraits<Traits, T>,
|
||||
|
||||
Fields,
|
||||
A, I, R, C,
|
||||
Inherited,
|
||||
Proto
|
||||
> {
|
||||
return new EffectSchemaTraitExpressionBuilder(
|
||||
this.expressionSuperclass,
|
||||
|
||||
traitsUnique([
|
||||
...this.expressionTraits,
|
||||
...spreadSupertraits(traits),
|
||||
]),
|
||||
)
|
||||
}
|
||||
}
|
||||
35
src/spreadSupertraits.ts
Normal file
35
src/spreadSupertraits.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Trait } from "./Trait"
|
||||
import { TraitExpression } from "./TraitExpression"
|
||||
|
||||
|
||||
export function spreadSupertraits<
|
||||
const T extends readonly Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
readonly Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return traits.flatMap(trait => [
|
||||
...trait.superExpression.traits,
|
||||
trait,
|
||||
]) as readonly Trait<any, any, any, any>[] as SpreadSupertraits<T>
|
||||
}
|
||||
|
||||
export type SpreadSupertraits<Traits> = (
|
||||
Traits extends readonly [
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
...infer Rest,
|
||||
]
|
||||
? readonly [
|
||||
...Trait.Supertraits<El>,
|
||||
El,
|
||||
...SpreadSupertraits<Rest>,
|
||||
]
|
||||
: readonly []
|
||||
)
|
||||
39
src/traitsUnique.ts
Normal file
39
src/traitsUnique.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { unique } from "remeda"
|
||||
import { IsEqual } from "type-fest"
|
||||
import { Trait } from "./Trait"
|
||||
import { TraitExpression } from "./TraitExpression"
|
||||
|
||||
|
||||
export function traitsUnique<
|
||||
const T extends readonly Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
readonly Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return unique(traits) as readonly Trait<any, any, any, any>[] as TraitsUnique<T>
|
||||
}
|
||||
|
||||
export type TraitsUnique<Traits> = (
|
||||
Traits extends readonly [
|
||||
...infer Rest,
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
]
|
||||
? IsTraitInTupleFromRight<Rest, El> extends true
|
||||
? TraitsUnique<Rest>
|
||||
: readonly [...TraitsUnique<Rest>, El]
|
||||
: readonly []
|
||||
)
|
||||
type IsTraitInTupleFromRight<Traits, T> = (
|
||||
Traits extends readonly [...infer Rest, infer El]
|
||||
? IsEqual<El, T> extends true
|
||||
? true
|
||||
: IsTraitInTupleFromRight<Rest, T>
|
||||
: false
|
||||
)
|
||||
Reference in New Issue
Block a user