diff --git a/src/result/result.interface.ts b/src/result/result.interface.ts index 55ee892..5ff4e90 100644 --- a/src/result/result.interface.ts +++ b/src/result/result.interface.ts @@ -19,6 +19,16 @@ export interface IResult { map(fn: (val: T) => M): IResult mapFail(fn: (err: E) => M): IResult flatMap(fn: (val: T) => IResult): IResult + + /** + * Convert Ok result into Fail using projected value from Ok + */ + toFailWhenOk(fn: (val: T) => E): IResult + + /** + * Convert Ok result into Fail using a provided value + */ + toFailWhenOkFrom(val: E): IResult } export interface IResultOk extends IResult { diff --git a/src/result/result.spec.ts b/src/result/result.spec.ts index 707dd94..ba50fe7 100644 --- a/src/result/result.spec.ts +++ b/src/result/result.spec.ts @@ -157,4 +157,46 @@ describe('result', () => { expect(sut.isOk()).toEqual(true) }) }) + + describe('toFailIfExists', () => { + it('should toFailWhenOk', () => { + const sut = ok(1) + .map(a => a + 2) + .toFailWhenOk(a => new Error(`only have ${a}`)) + + expect(sut.isFail()).toEqual(true) + expect(sut.unwrapFail()).toBeInstanceOf(Error) + expect(sut.unwrapFail().message).toEqual('only have 3') + }) + + it('should toFailWhenOkFrom from fail', () => { + const sut = fail(new Error('started as error')) + .map(a => a + 2) + .toFailWhenOkFrom(new Error('ended as an error')) + + expect(sut.isFail()).toEqual(true) + expect(sut.unwrapFail()).toBeInstanceOf(Error) + expect(sut.unwrapFail().message).toEqual('ended as an error') + }) + + it('should toFailWhenOk from fail', () => { + const sut = fail(new Error('started as error')) + .map(a => a + 2) + .toFailWhenOk(a => new Error(`ended as an error ${a}`)) + + expect(sut.isFail()).toEqual(true) + expect(sut.unwrapFail()).toBeInstanceOf(Error) + expect(sut.unwrapFail().message).toEqual('started as error') + }) + + it('should toFailWhenOkFrom', () => { + const sut = ok(1) + .map(a => a + 2) + .toFailWhenOkFrom(new Error('error msg')) + + expect(sut.isFail()).toEqual(true) + expect(sut.unwrapFail()).toBeInstanceOf(Error) + expect(sut.unwrapFail().message).toEqual('error msg') + }) + }) }) diff --git a/src/result/result.ts b/src/result/result.ts index 9d9eea5..a6d5847 100644 --- a/src/result/result.ts +++ b/src/result/result.ts @@ -23,6 +23,8 @@ export abstract class Result implements IResult { abstract map(fn: (val: TOk) => M): IResult abstract mapFail(fn: (err: TFail) => M): IResult abstract flatMap(fn: (val: TOk) => IResult): IResult + abstract toFailWhenOk(fn: (val: TOk) => TFail): IResult + abstract toFailWhenOkFrom(val: TFail): IResult } export class OkResult extends Result { @@ -74,6 +76,13 @@ export class OkResult extends Result { return fn(this.successValue) } + toFailWhenOk(fn: (val: TOk) => TFail): IResult { + return Result.fail(fn(this.successValue)) + } + + toFailWhenOkFrom(val: TFail): IResult { + return Result.fail(val) + } } export class FailResult extends Result implements IResult { @@ -124,4 +133,12 @@ export class FailResult extends Result implements IResul flatMap(): IResult { return Result.fail(this.failureValue) } + + toFailWhenOk(): IResult { + return this + } + + toFailWhenOkFrom(val: TFail): IResult { + return Result.fail(val) + } }