UNPKG

@parischap/conversions

Version:

A functional library to replace partially the native Intl API

210 lines 8.08 kB
/** * An extension to the `Effect.Schema` module that adds Schema instances for number and date * formatting and parsing and implements new brands */ import * as MMatch from '@parischap/effect-lib/MMatch'; import * as MTuple from '@parischap/effect-lib/MTuple'; import * as Array from 'effect/Array'; import * as Either from 'effect/Either'; import {flow} from 'effect/Function'; import * as Option from 'effect/Option'; import * as ParseResult from 'effect/ParseResult'; import {pipe} from 'effect/Function'; import * as Record from 'effect/Record'; import * as Schema from 'effect/Schema'; import * as CVDateTime from './DateTime.js'; import * as CVDateTimeFormat from './DateTimeFormat.js'; import * as CVEmail from './Email.js'; import * as CVInteger from './Integer.js'; import * as CVNumberBase10Format from './NumberBase10Format.js'; import * as CVPositiveInteger from './PositiveInteger.js'; import * as CVPositiveReal from './PositiveReal.js'; import * as CVReal from './Real.js'; import * as CVSemVer from './SemVer.js'; import * as CVTemplate from './Template.js'; import * as CVTemplatePart from './TemplatePart.js'; import * as CVTemplatePlaceholder from './TemplatePlaceholder.js'; /** * A `Schema` that transforms a string into a `CVEmail` * * @category Schema transformations */ export const Email = CVEmail.SchemaFromString; /** * A `Schema` that represents a `CVEmail` * * @category Schema instances */ export const EmailFromSelf = CVEmail.SchemaFromSelf; /** * A `Schema` that transforms a string into a `CVSemVer` * * @category Schema transformations */ export const SemVer = CVSemVer.SchemaFromString; /** * A `Schema` that represents a `CVSemVer` * * @category Schema instances */ export const SemVerFromSelf = CVSemVer.SchemaFromSelf; /** * A `Schema` that transforms a number into a `CVReal` * * @category Schema transformations */ export const RealFromNumber = CVReal.SchemaFromNumber; /** * A `Schema` that represents `CVReal` * * @category Schema instances */ export const RealFromSelf = CVReal.SchemaFromSelf; /** * A `Schema` that transforms a string into a `CVReal` according to the `format`. Read documentation * of module NumberBase10Format.ts for more details * * @category Schema transformations */ export const Real = format => { const parser = CVNumberBase10Format.toRealParser(format); const formatter = CVNumberBase10Format.toNumberFormatter(format); return Schema.transformOrFail(Schema.String, RealFromSelf, { strict: true, decode: (input, _options, ast) => pipe(input, parser, Either.fromOption(() => new ParseResult.Type(ast, input, 'Failed to convert string to a(n) ' + CVNumberBase10Format.toDescription(format)))), encode: flow(formatter, ParseResult.succeed) }); }; /** * A `Schema` that transforms a number into a `CVInteger` * * @category Schema transformations */ export const IntegerFromNumber = CVInteger.SchemaFromNumber; /** * A `Schema` that represents a `CVInteger` * * @category Schema instances */ export const IntegerFromSelf = CVInteger.SchemaFromSelf; /** * A `Schema` that transforms a number into a `CVPositiveInteger` * * @category Schema transformations */ export const PositiveIntegerFromNumber = CVPositiveInteger.SchemaFromNumber; /** * A `Schema` that represents a `CVPositiveInteger` * * @category Schema instances */ export const PositiveIntegerFromSelf = CVPositiveInteger.SchemaFromSelf; /** * A `Schema` that transforms a number into a `CVPositiveReal` * * @category Schema transformations */ export const PositiveRealFromNumber = CVPositiveReal.SchemaFromNumber; /** * A `Schema` that represents a `CVPositiveReal` * * @category Schema instances */ export const PositiveRealFromSelf = CVPositiveReal.SchemaFromSelf; const BigDecimalFromString = format => { const parser = CVNumberBase10Format.toBigDecimalParser(format); const formatter = CVNumberBase10Format.toNumberFormatter(format); return Schema.transformOrFail(Schema.String, Schema.BigDecimalFromSelf, { strict: true, decode: (input, _options, ast) => pipe(input, parser, Option.map(ParseResult.succeed), Option.getOrElse(() => ParseResult.fail(new ParseResult.Type(ast, input, 'Failed to convert string to a(n) ' + CVNumberBase10Format.toDescription(format))))), encode: flow(formatter, ParseResult.succeed) }); }; export { /** * A `Schema` that transforms a string into a `BigDecimal` according to `format`. Read * documentation of module NumberBase10Format.ts for more details * * @category Schema transformations */ BigDecimalFromString as BigDecimal }; /** * A `Schema` that represents a `CVDateTime` * * @category Schema instances */ export const DateTimeFromSelf = /*#__PURE__*/Schema.declare(input => CVDateTime.has(input)); /** * A `Schema` that transforms a `CVDateTime` into a Javascript `Date`. Upon encoding, the * `CVDateTime` object is created with the default timeZoneOffset of the machine this code is * running on * * @category Schema instances */ export const DateFromDateTime = /*#__PURE__*/Schema.transform(DateTimeFromSelf, Schema.DateFromSelf, { strict: true, decode: CVDateTime.toDate, encode: CVDateTime.fromDate }); /** * A `Schema` that transforms a `CVDateTime` into an `Effect.DateTime.Zoned`. Both objects share the * same time zone offset * * @category Schema instances */ export const DateTimeZonedFromDateTime = /*#__PURE__*/Schema.transform(DateTimeFromSelf, Schema.DateTimeZonedFromSelf, { strict: true, decode: CVDateTime.toEffectDateTime, encode: CVDateTime.fromEffectDateTime }); const DateTimeFromString = format => { const parser = CVDateTimeFormat.toParser(format); const formatter = CVDateTimeFormat.toFormatter(format); return Schema.transformOrFail(Schema.String, DateTimeFromSelf, { strict: true, decode: (input, _options, ast) => pipe(input, parser, Either.mapLeft(inputError => new ParseResult.Type(ast, input, inputError.message))), encode: (input, _options, ast) => pipe(input, formatter, Either.mapLeft(inputError => new ParseResult.Type(ast, input, inputError.message))) }); }; export { /** * A `Schema` that transforms a string into a `CVDateTime` according to `format`. Read * documentation of module DateTimeFormat.ts for more details * * @category Schema transformations */ DateTimeFromString as DateTime }; /** * A `Schema` that transforms a string into a Javascript `Date` according to `format`. Read * documentation of module DateTimeFormat.ts for more details * * @category Schema transformations */ export const Date = format => Schema.compose(DateTimeFromString(format), DateFromDateTime); /** * A `Schema` that transforms a string into an `Effect.DateTime.Zoned` according to `format`. Read * documentation of module DateTimeFormat.ts for more details * * @category Schema transformations */ export const DateTimeZoned = format => Schema.compose(DateTimeFromString(format), DateTimeZonedFromDateTime); /** * A `Schema` that transforms a string into an object according to template. Read documentation of * module Template.ts for more details * * @category Schema transformations */ export const Template = template => { const parser = CVTemplate.toParser(template); const formatter = CVTemplate.toFormatter(template); const schemaOutput = pipe(template.templateParts, Array.filterMap(flow(MMatch.make, MMatch.when(CVTemplatePart.isSeparator, () => Option.none()), MMatch.when(CVTemplatePart.isPlaceholder, flow(MTuple.makeBothBy({ toFirst: CVTemplatePlaceholder.name, toSecond: CVTemplatePlaceholder.tSchemaInstance }), Option.some)), MMatch.exhaustive)), Record.fromEntries, Schema.Struct); return Schema.transformOrFail(Schema.String, schemaOutput, { strict: true, decode: (input, _options, ast) => pipe(input, parser, Either.mapLeft(inputError => new ParseResult.Type(ast, input, inputError.message))), encode: (input, _options, ast) => pipe(input, formatter, Either.mapLeft(inputError => new ParseResult.Type(ast, input, inputError.message))) }); }; //# sourceMappingURL=Schema.js.map