module import type Maybe from './maybe.js' ; import Unit from './unit.js' ; import { curry1 , isVoid } from './-private/utils.js' ; import * as Toolbelt from './toolbelt.js' ; /**
  Discriminant for {@linkcode Ok} and {@linkcode Err} variants of the
  {@linkcode Result} type.

  You can use the discriminant via the `variant` property of `Result` instances
  if you need to match explicitly on it.
 */ export const Variant = { Ok : 'Ok' , Err : 'Err' , } as const ; export type Variant = keyof typeof Variant ; export interface OkJSON < T > { variant : 'Ok' ; value : T ; } export interface ErrJSON < E > { variant : 'Err' ; error : E ; } export type ResultJSON < T , E > = OkJSON < T > | ErrJSON < E > ; type Repr < T , E > = [ tag : 'Ok' , value : T ] | [ tag : 'Err' , error : E ] ; class ResultImpl < T , E > { private constructor ( private repr ) { } param value static ok < T , E > ( ) ; static ok < T , E > ( value ) ; static ok < T , E > ( value ? ) { return isVoid ( value ) ? ( new ResultImpl < Unit , E > ( [ 'Ok' , Unit ] ) as Result < Unit , E > ) : ( new ResultImpl < T , E > ( [ 'Ok' , value ] ) as Result < T , E > ) ; } param error static err < T , E > ( ) ; static err < T , E > ( error ) ; static err < T , E > ( error ? ) { return isVoid ( error ) ? ( new ResultImpl < T , Unit > ( [ 'Err' , Unit ] ) as Result < T , Unit > ) : ( new ResultImpl < T , E > ( [ 'Err' , error ] ) as Result < T , E > ) ; } /** Distinguish between the {@linkcode Variant.Ok} and {@linkcode Variant.Err} {@linkcode Variant variants}. */ get variant ( ) : Variant { return this . repr [ 0 ] ; } throws get value ( ) : T | never { if ( this . repr [ 0 ] === Variant . Err ) { throw new Error ( 'Cannot get the value of Err' ) ; } return this . repr [ 1 ] ; } throws get error ( ) : E | never { if ( this . repr [ 0 ] === Variant . Ok ) { throw new Error ( 'Cannot get the error of Ok' ) ; } return this . repr [ 1 ] ; } /** Is the {@linkcode Result} an {@linkcode Ok}? */ get isOk ( ) { return this . repr [ 0 ] === Variant . Ok ; } /** Is the `Result` an `Err`? */ get isErr ( ) { return this . repr [ 0 ] === Variant . Err ; } /** Method variant for {@linkcode map} */ map < U > ( this , mapFn ) { return map ( mapFn , this ) ; } /** Method variant for {@linkcode mapOr} */ mapOr < U > ( this , orU , mapFn ) { return mapOr ( orU , mapFn , this ) ; } /** Method variant for {@linkcode mapOrElse} */ mapOrElse < U > ( this , orElseFn , mapFn ) { return mapOrElse ( orElseFn , mapFn , this ) ; } /** Method variant for {@linkcode match} */ match < U > ( this , matcher ) { return match ( matcher , this ) ; } /** Method variant for {@linkcode mapErr} */ mapErr < F > ( this , mapErrFn ) { return mapErr ( mapErrFn , this ) ; } /** Method variant for {@linkcode or} */ or < F > ( this , orResult ) { return or ( orResult , this ) ; } /** Method variant for {@linkcode orElse} */ orElse < F > ( this , orElseFn ) { return orElse ( orElseFn , this ) ; } /** Method variant for {@linkcode and} */ and < U > ( this , mAnd ) { return and ( mAnd , this ) ; } /** Method variant for {@linkcode andThen} */ andThen < U > ( this , andThenFn ) { return andThen ( andThenFn , this ) ; } /** Method variant for {@linkcode unwrapOr} */ unwrapOr < U = T > ( this , defaultValue ) { return unwrapOr ( defaultValue , this ) ; } /** Method variant for {@linkcode unwrapOrElse} */ unwrapOrElse < U > ( this , elseFn ) { return unwrapOrElse ( elseFn , this ) ; } deprecated toMaybe ( this ) { return Toolbelt . toMaybe ( this ) ; } /** Method variant for {@linkcode toString} */ toString ( this ) { return toString ( this ) ; } /** Method variant for {@linkcode toJSON} */ toJSON ( this ) { return toJSON ( this ) ; } /** Method variant for {@linkcode equals} */ equals ( this , comparison ) { return equals ( comparison , this ) ; } /** Method variant for {@linkcode ap} */ ap < A , B > ( this , r ) { return ap ( this , r ) ; } } typeparam typeparam export interface Ok < T , E > extends ResultImpl < T , E > { /** `Ok` is always [`Variant.Ok`](../enums/_result_.variant#ok). */ variant : 'Ok' ; isOk : true ; isErr : false ; /** The wrapped value */ value : T ; internal error : never ; } typeparam typeparam export interface Err < T , E > extends ResultImpl < T , E > { /** `Err` is always [`Variant.Err`](../enums/_result_.variant#err). */ readonly variant : 'Err' ; isOk : false ; isErr : true ; internal value : never ; /** The wrapped error value. */ error : E ; } param error param callback export function tryOr < T , E > ( error , callback ) ; export function tryOr < T , E > ( error ) ; export function tryOr < T , E > ( error , callback ? ) { const op = ( cb ) => { try { return ok < T , E > ( cb ( ) ) ; } catch { return err < T , E > ( error ) ; } } ; return curry1 ( op , callback ) ; } typeparam param value export const ok = ResultImpl . ok ; typeparam param E export const err = ResultImpl . err ; param onError param callback export function tryOrElse < T , E > ( onError , callback ) ; export function tryOrElse < T , E > ( onError ) ; export function tryOrElse < T , E > ( onError , callback ? ) { const op = ( cb ) => { try { return ok < T , E > ( cb ( ) ) ; } catch ( e ) { return err < T , E > ( onError ( e ) ) ; } } ; return curry1 ( op , callback ) ; } typeparam typeparam typeparam param mapFn param result returns export function map < T , U , E > ( mapFn , result ) ; export function map < T , U , E > ( mapFn ) ; export function map < T , U , E > ( mapFn , result ? ) { const op = ( r ) => ( r . isOk ? ok ( mapFn ( r . value ) ) : r ) as Result < U , E > ; return curry1 ( op , result ) ; } param orU param mapFn param result export function mapOr < T , U , E > ( orU , mapFn , result ) ; export function mapOr < T , U , E > ( orU , mapFn ) ; export function mapOr < T , U , E > ( orU ) ; export function mapOr < T , U , E > ( orU , mapFn ? , result ? ) { function fullOp ( fn , r ) { return r . isOk ? fn ( r . value ) : orU ; } function partialOp ( fn ) ; function partialOp ( fn , curriedResult ) ; function partialOp ( fn , curriedResult ? ) { return curriedResult !== undefined ? fullOp ( fn , curriedResult ) : ( extraCurriedResult ) => fullOp ( fn , extraCurriedResult ) ; } return mapFn === undefined ? partialOp : result === undefined ? partialOp ( mapFn ) : partialOp ( mapFn , result ) ; } typeparam typeparam typeparam param orElseFn param mapFn param result export function mapOrElse < T , U , E > ( orElseFn , mapFn , result ) ; export function mapOrElse < T , U , E > ( orElseFn , mapFn ) ; export function mapOrElse < T , U , E > ( orElseFn ) ; export function mapOrElse < T , U , E > ( orElseFn , mapFn ? , result ? ) { function fullOp ( fn , r ) { return r . isOk ? fn ( r . value ) : orElseFn ( r . error ) ; } function partialOp ( fn ) ; function partialOp ( fn , curriedResult ) ; function partialOp ( fn , curriedResult ? ) { return curriedResult !== undefined ? fullOp ( fn , curriedResult ) : ( extraCurriedResult ) => fullOp ( fn , extraCurriedResult ) ; } return mapFn === undefined ? partialOp : result === undefined ? partialOp ( mapFn ) : partialOp ( mapFn , result ) ; } typeparam typeparam typeparam param mapErrFn param result export function mapErr < T , E , F > ( mapErrFn , result ) ; export function mapErr < T , E , F > ( mapErrFn ) ; export function mapErr < T , E , F > ( mapErrFn , result ? ) { const op = ( r ) => ( r . isOk ? r : err ( mapErrFn ( r . error ) ) ) as Result < T , F > ; return curry1 ( op , result ) ; } typeparam typeparam typeparam param andResult param result export function and < T , U , E > ( andResult , result ) ; export function and < T , U , E > ( andResult ) ; export function and < T , U , E > ( andResult , result ? ) { const op = ( r ) => ( r . isOk ? andResult : err < U , E > ( r . error ) ) ; return curry1 ( op , result ) ; } typeparam typeparam typeparam param thenFn param result export function andThen < T , U , E > ( thenFn , result ) ; export function andThen < T , U , E > ( thenFn ) ; export function andThen < T , U , E > ( thenFn , result ? ) { const op = ( r ) => ( r . isOk ? thenFn ( r . value ) : err < U , E > ( r . error ) ) ; return curry1 ( op , result ) ; } typeparam typeparam typeparam param defaultResult param result returns export function or < T , E , F > ( defaultResult , result ) ; export function or < T , E , F > ( defaultResult ) ; export function or < T , E , F > ( defaultResult , result ? ) { const op = ( r ) => ( r . isOk ? ok < T , F > ( r . value ) : defaultResult ) ; return curry1 ( op , result ) ; } param elseFn param result returns export function orElse < T , E , F > ( elseFn , result ) ; export function orElse < T , E , F > ( elseFn ) ; export function orElse < T , E , F > ( elseFn , result ? ) { const op = ( r ) => ( r . isOk ? ok < T , F > ( r . value ) : elseFn ( r . error ) ) ; return curry1 ( op , result ) ; } typeparam typeparam param defaultValue param result returns export function unwrapOr < T , U , E > ( defaultValue , result ) ; export function unwrapOr < T , U , E > ( defaultValue ) ; export function unwrapOr < T , U , E > ( defaultValue , result ? ) { const op = ( r ) => ( r . isOk ? r . value : defaultValue ) ; return curry1 ( op , result ) ; } typeparam typeparam param orElseFn param result returns export function unwrapOrElse < T , U , E > ( orElseFn , result ) ; export function unwrapOrElse < T , U , E > ( orElseFn ) ; export function unwrapOrElse < T , U , E > ( orElseFn , result ? ) { const op = ( r ) => ( r . isOk ? r . value : orElseFn ( r . error ) ) ; return curry1 ( op , result ) ; } deprecated export function fromMaybe < T , E > ( errValue , maybe ) ; export function fromMaybe < T , E > ( errValue ) ; export function fromMaybe < T , E > ( errValue , maybe ? ) { const op = ( m ) => ( m . isJust ? ok < T , E > ( m . value ) : err < T , E > ( errValue ) ) ; return curry1 ( op , maybe ) ; } typeparam param maybe returns export const toString = < T extends { toString ( ) : string ; } , E extends { toString ( ) : string ; } > ( result ) : string => { const body = ( result . isOk ? result . value : result . error ) . toString ( ) ; return `${ result . variant . toString ( ) }(${ body })` ; } ; param result returns export const toJSON = < T , E > ( result ) : ResultJSON < T , E > => { return result . isOk ? { variant : result . variant , value : result . value } : { variant : result . variant , error : result . error } ; } ; /**
  A lightweight object defining how to handle each variant of a
  {@linkcode Result}.
 */ export type Matcher < T , E , A > = { Ok : ( value : T ) => A ; Err : ( error : E ) => A ; } ; param matcher param maybe export function match < T , E , A > ( matcher , result ) ; export function match < T , E , A > ( matcher ) ; export function match < T , E , A > ( matcher , result ? ) { const op = ( r ) => mapOrElse ( matcher . Err , matcher . Ok , r ) ; return curry1 ( op , result ) ; } param resultB param resultA export function equals < T , E > ( resultB , resultA ) ; export function equals < T , E > ( resultB ) ; export function equals < T , E > ( resultB , resultA ? ) { return resultA !== undefined ? resultA . match ( { Err : ( ) => resultB . isErr , Ok : ( a ) => resultB . isOk && resultB . value === a , } ) : ( curriedResultA ) => curriedResultA . match ( { Err : ( ) => resultB . isErr , Ok : ( a ) => resultB . isOk && resultB . value === a , } ) ; } param resultFn param result export function ap < T , U , E > ( resultFn , result ) ; export function ap < T , U , E > ( resultFn ) ; export function ap < T , U , E > ( resultFn , result ? ) { const op = ( r ) => r . andThen ( ( val ) => resultFn . map ( ( fn ) => fn ( val ) ) ) ; return curry1 ( op , result ) ; } param item export function isInstance < T , E > ( item ) { return item instanceof ResultImpl ; } deprecated export function transposeMaybe < T , E > ( maybe ) { return Toolbelt . transposeMaybe ( maybe ) ; } deprecated export function toMaybe < T , E > ( result ) { return Toolbelt . toMaybe ( result ) ; } export interface ResultConstructor { ok : typeof ResultImpl . ok ; err : typeof ResultImpl . err ; } /**
  A value which may ({@linkcode Ok}) or may not ({@linkcode Err}) be present.

  The behavior of this type is checked by TypeScript at compile time, and bears
  no runtime overhead other than the very small cost of the container object.
 */ export type Result < T , E > = Ok < T , E > | Err < T , E > ; export const Result = ResultImpl as ResultConstructor ; export default Result ;