/** * @since 1.0.0 * * Serializable represents an object that has self-contained Schema(s) */ import type * as Effect from "effect/Effect" import type * as Exit from "effect/Exit" import { dual } from "effect/Function" import { globalValue } from "effect/GlobalValue" import * as Internal from "./internal/serializable.js" import type * as ParseResult from "./ParseResult.js" import * as Schema from "./Schema.js" /** * @since 1.0.0 * @category symbol */ export const symbol: unique symbol = Internal.symbol as any /** * @since 1.0.0 * @category model */ export interface Serializable { readonly [symbol]: Schema.Schema } /** * @since 1.0.0 * @category model */ export declare namespace Serializable { /** * @since 1.0.0 */ export type Context = T extends Serializable ? R : never } /** * @since 1.0.0 * @category accessor */ export const selfSchema = (self: Serializable): Schema.Schema => self[symbol] /** * @since 1.0.0 * @category symbol */ export const symbolResult: unique symbol = Internal.symbolResult as any /** * @since 1.0.0 * @category model */ export interface WithResult { readonly [symbolResult]: { readonly Failure: Schema.Schema readonly Success: Schema.Schema } } /** * @since 1.0.0 * @category model */ export declare namespace WithResult { /** * @since 1.0.0 */ export type Context = T extends WithResult ? R : never } /** * @since 1.0.0 * @category accessor */ export const failureSchema = ( self: WithResult ): Schema.Schema => self[symbolResult].Failure /** * @since 1.0.0 * @category accessor */ export const successSchema = ( self: WithResult ): Schema.Schema => self[symbolResult].Success const exitSchemaCache = globalValue( "@effect/schema/Serializable/exitSchemaCache", () => new WeakMap>() ) /** * @since 1.0.0 * @category accessor */ export const exitSchema = ( self: WithResult ): Schema.Schema, Exit.Exit> => { const proto = Object.getPrototypeOf(self) if (!(symbolResult in proto)) { return Schema.exit(failureSchema(self), successSchema(self)) } let schema = exitSchemaCache.get(proto) if (schema === undefined) { schema = Schema.exit(failureSchema(self), successSchema(self)) exitSchemaCache.set(proto, schema) } return schema } /** * @since 1.0.0 * @category model */ export interface SerializableWithResult extends Serializable, WithResult {} /** * @since 1.0.0 * @category model */ export declare namespace SerializableWithResult { /** * @since 1.0.0 */ export type Context = T extends SerializableWithResult ? R | RR : never } /** * @since 1.0.0 * @category encoding */ export const serialize = ( self: Serializable ): Effect.Effect => Schema.encode(self[symbol])(self as A) /** * @since 1.0.0 * @category decoding */ export const deserialize: { ( value: unknown ): (self: Serializable) => Effect.Effect (self: Serializable, value: unknown): Effect.Effect } = dual< (value: unknown) => ( self: Serializable ) => Effect.Effect, ( self: Serializable, value: unknown ) => Effect.Effect >(2, (self, value) => Schema.decodeUnknown(self[symbol])(value)) /** * @since 1.0.0 * @category encoding */ export const serializeFailure: { ( value: E ): (self: WithResult) => Effect.Effect ( self: WithResult, value: E ): Effect.Effect } = dual< (value: E) => ( self: WithResult ) => Effect.Effect, ( self: WithResult, value: E ) => Effect.Effect >(2, (self, value) => Schema.encode(self[symbolResult].Failure)(value)) /** * @since 1.0.0 * @category decoding */ export const deserializeFailure: { (value: unknown): ( self: WithResult ) => Effect.Effect ( self: WithResult, value: unknown ): Effect.Effect } = dual< (value: unknown) => ( self: WithResult ) => Effect.Effect, ( self: WithResult, value: unknown ) => Effect.Effect >(2, (self, value) => Schema.decodeUnknown(self[symbolResult].Failure)(value)) /** * @since 1.0.0 * @category encoding */ export const serializeSuccess: { ( value: A ): (self: WithResult) => Effect.Effect ( self: WithResult, value: A ): Effect.Effect } = dual< (value: A) => ( self: WithResult ) => Effect.Effect, ( self: WithResult, value: A ) => Effect.Effect >(2, (self, value) => Schema.encode(self[symbolResult].Success)(value)) /** * @since 1.0.0 * @category decoding */ export const deserializeSuccess: { ( value: unknown ): ( self: WithResult ) => Effect.Effect ( self: WithResult, value: unknown ): Effect.Effect } = dual< (value: unknown) => ( self: WithResult ) => Effect.Effect, ( self: WithResult, value: unknown ) => Effect.Effect >(2, (self, value) => Schema.decodeUnknown(self[symbolResult].Success)(value)) /** * @since 1.0.0 * @category encoding */ export const serializeExit: { ( value: Exit.Exit ): ( self: WithResult ) => Effect.Effect> ( self: WithResult, value: Exit.Exit ): Effect.Effect> } = dual< (value: Exit.Exit) => ( self: WithResult ) => Effect.Effect>, ( self: WithResult, value: Exit.Exit ) => Effect.Effect> >(2, (self, value) => Schema.encode(exitSchema(self))(value)) /** * @since 1.0.0 * @category decoding */ export const deserializeExit: { (value: unknown): ( self: WithResult ) => Effect.Effect> ( self: WithResult, value: unknown ): Effect.Effect> } = dual< (value: unknown) => ( self: WithResult ) => Effect.Effect>, ( self: WithResult, value: unknown ) => Effect.Effect> >(2, (self, value) => Schema.decodeUnknown(exitSchema(self))(value))