/** * Represents an exclusion of a supplied value where the exclusion is mapped to `None`. * Requires an inner schemable, and an Eq instance which defaults to strict equality. * * @since 0.0.4 */ import { Kind, Kind2, URIS, URIS2, HKT2 } from 'fp-ts/HKT' import * as D from 'io-ts/Decoder' import * as Enc from 'io-ts/Encoder' import * as Eq_ from 'fp-ts/Eq' import * as E from 'fp-ts/Either' import * as fc from 'fast-check' import * as TE from 'fp-ts/TaskEither' import * as G from 'io-ts/Guard' import * as TD from 'io-ts/TaskDecoder' import * as t from 'io-ts/Type' import * as O from 'fp-ts/Option' import * as Arb from '../internal/ArbitraryBase' import { flow, SK } from 'fp-ts/function' /** * @since 0.0.4 * @category Model */ export type SchemableParams = ( exclude: B, sa: HKT2, eqA?: Eq_.Eq ) => HKT2> /** * @since 0.0.4 * @category Model */ export type SchemableParams1 = ( exclude: B, sa: Kind, eqA?: Eq_.Eq ) => Kind> /** * @since 0.0.4 * @category Model */ export type SchemableParams2 = ( exclude: B, sa: Kind2, eqA?: Eq_.Eq ) => Kind2> /** * @since 0.0.4 * @category Model */ export type SchemableParams2C = ( exclude: B, sa: Kind2, eqA?: Eq_.Eq ) => Kind2> /** * @since 0.0.4 * @category Instances */ export const Decoder: SchemableParams2C = (exclude, sa, eqA = Eq_.eqStrict) => ({ decode: flow(sa.decode, E.map(O.fromPredicate(a => !eqA.equals(a, exclude)))), }) /** * @since 0.0.4 * @category Instances */ export const Encoder: SchemableParams2 = (exclude, sa) => ({ encode: flow( O.getOrElseW(() => exclude), sa.encode ), }) /** * @since 0.0.4 * @category Instances */ export const Eq: SchemableParams1 = flow(SK, O.getEq) /** * @since 0.0.4 * @category Instances */ export const Guard: SchemableParams1 = (_, guardA) => G.union( G.struct({ _tag: G.literal('None'), }), G.struct({ _tag: G.literal('Some'), value: guardA, }) ) /** * @since 0.0.4 * @category Instances */ export const TaskDecoder: SchemableParams2C = ( exclude, sa, eqA = Eq_.eqStrict ) => ({ decode: flow(sa.decode, TE.map(O.fromPredicate(a => !eqA.equals(a, exclude)))), }) /** * @since 0.0.4 * @category Instances */ export const Type: SchemableParams1 = (_, typeA) => t.union( t.struct({ _tag: t.literal('None'), }), t.struct({ _tag: t.literal('Some'), value: typeA, }) ) /** * @since 0.0.4 * @category Instances */ export const Arbitrary: SchemableParams1 = (_, arbA) => fc.oneof( Arb.struct({ _tag: Arb.literal('None') }), Arb.struct({ _tag: Arb.literal('Some'), value: arbA }) )