Skip to content

Commit

Permalink
feat: add Result.toFailWhenOk() (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickmichalina authored Nov 3, 2022
1 parent 4655e5d commit efe0852
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/result/result.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ export interface IResult<T, E> {
map<M>(fn: (val: T) => M): IResult<M, E>
mapFail<M>(fn: (err: E) => M): IResult<T, M>
flatMap<M>(fn: (val: T) => IResult<M, E>): IResult<M, E>

/**
* Convert Ok result into Fail using projected value from Ok
*/
toFailWhenOk(fn: (val: T) => E): IResult<T, E>

/**
* Convert Ok result into Fail using a provided value
*/
toFailWhenOkFrom(val: E): IResult<T, E>
}

export interface IResultOk<T, E = never> extends IResult<T, E> {
Expand Down
42 changes: 42 additions & 0 deletions src/result/result.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,46 @@ describe('result', () => {
expect(sut.isOk()).toEqual(true)
})
})

describe('toFailIfExists', () => {
it('should toFailWhenOk', () => {
const sut = ok<number, Error>(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<number, Error>(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<number, Error>(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<number, Error>(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')
})
})
})
17 changes: 17 additions & 0 deletions src/result/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export abstract class Result<TOk, TFail> implements IResult<TOk, TFail> {
abstract map<M>(fn: (val: TOk) => M): IResult<M, TFail>
abstract mapFail<M>(fn: (err: TFail) => M): IResult<TOk, M>
abstract flatMap<M>(fn: (val: TOk) => IResult<M, TFail>): IResult<M, TFail>
abstract toFailWhenOk(fn: (val: TOk) => TFail): IResult<TOk, TFail>
abstract toFailWhenOkFrom(val: TFail): IResult<TOk, TFail>
}

export class OkResult<TOk, TFail> extends Result<TOk, TFail> {
Expand Down Expand Up @@ -74,6 +76,13 @@ export class OkResult<TOk, TFail> extends Result<TOk, TFail> {
return fn(this.successValue)
}

toFailWhenOk(fn: (val: TOk) => TFail): IResult<TOk, TFail> {
return Result.fail(fn(this.successValue))
}

toFailWhenOkFrom(val: TFail): IResult<TOk, TFail> {
return Result.fail(val)
}
}

export class FailResult<TOk, TFail> extends Result<TOk, TFail> implements IResult<TOk, TFail> {
Expand Down Expand Up @@ -124,4 +133,12 @@ export class FailResult<TOk, TFail> extends Result<TOk, TFail> implements IResul
flatMap<M>(): IResult<M, TFail> {
return Result.fail(this.failureValue)
}

toFailWhenOk(): IResult<TOk, TFail> {
return this
}

toFailWhenOkFrom(val: TFail): IResult<TOk, TFail> {
return Result.fail(val)
}
}

0 comments on commit efe0852

Please sign in to comment.