import { InvalidStateError } from "../client.js" /** * @tsplus getter function asCollectable */ export function asCollectable(refinement: Refinement) { return Opt.liftPredicate(refinement) } /** * @tsplus fluent function as */ export function as(refinement: Refinement, name: string) { return flow( asCollectable(refinement), _ => _.encaseInEither(() => new InvalidStateError({ message: `Cannot be ${name}` })) ) } /** * @tsplus fluent function refinements */ export function makeAwesome(refinement: Refinement, name: string) { const as = refinement.as(name) const validate = { is: refinement, collect: refinement.asCollectable, as, asEffect: flow(as, Effect.fromEither), lens: Lens.id() } function validatei(item: T) { return { get collect() { return validate.collect(item) }, get as() { return validate.as(item) }, get asEffect() { return validate.asEffect(item) } } } return { ...validate, $item: validatei } } // The idea is that such refinements are dynamic export interface Collect { (a: A): Opt } /** * @tsplus fluent function as */ export function asOpt(collect: Collect, name: string) { return flow(collect, _ => _.encaseInEither(() => new InvalidStateError({ message: `Cannot be ${name}` }))) } /** * @tsplus fluent function refinements */ export function makeAwesomeCollect(collect: Collect, name: string) { const as = collect.as(name) function is(item: T): item is T2 { return collect(item).isSome() } const validate = { collect, is, as, asEffect: flow(as, Effect.fromEither), lens: Lens.id() } function validatei(item: T) { return { get collect() { return validate.collect(item) }, get as() { return validate.as(item) }, get asEffect() { return validate.asEffect(item) } } } return { ...validate, $item: validatei } } export type GetCollectedType = T extends { collect: Collect } ? U : never