Skip to content

Commit

Permalink
[dsch] introducing Result.apply method
Browse files Browse the repository at this point in the history
  • Loading branch information
DScheglov committed Sep 23, 2024
1 parent 8429a87 commit 38a845e
Show file tree
Hide file tree
Showing 6 changed files with 375 additions and 54 deletions.
4 changes: 4 additions & 0 deletions src/Err.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ export class ErrImpl<E> implements Err<E> {
biChain<S, F>(_: unknown, errFn: (error: E) => Result<S, F>): Result<S, F> {
return errFn(this.error);
}

apply() {
return this;
}
}

Object.defineProperty(ErrImpl, 'name', { enumerable: false, value: 'Err' });
Expand Down
16 changes: 15 additions & 1 deletion src/Ok.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { AsyncOk, Ok, Result } from './types';
import { resolveOks } from './resolve-args';
import type { AsyncOk, ErrTypeOf, Ok, ResolveOks, Result } from './types';

export class OkImpl<T> implements Ok<T> {
constructor(public readonly value: T) {}
Expand Down Expand Up @@ -87,6 +88,19 @@ export class OkImpl<T> implements Ok<T> {
biChain<S, F>(okFn: (data: T) => Result<S, F>): Result<S, F> {
return okFn(this.value);
}

apply<Args extends any[], R = never>(
this: OkImpl<(...args: ResolveOks<Args>) => R>,
...args: Args
): Result<R, ErrTypeOf<Args[number]>> {
if (typeof this.value !== 'function') {
throw new TypeError('Result.value is not a function', { cause: this });
}

const argValues = resolveOks(args);

return Array.isArray(argValues) ? ok(this.value(...argValues)) : argValues;
}
}

Object.defineProperty(OkImpl, 'name', { enumerable: false, value: 'Ok' });
Expand Down
20 changes: 20 additions & 0 deletions src/resolve-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { isResult } from './guards';
import { Err, ErrTypeOf, ResolveOks } from './types';

export const resolveOks = <PR extends any[]>(
args: PR,
): ResolveOks<PR> | Err<ErrTypeOf<PR[number]>> => {
const argValues = [] as any[];

for (const arg of args) {
if (!isResult(arg)) {
argValues.push(arg);
} else if (arg.isErr) {
return arg as Err<ErrTypeOf<PR[number]>>;
} else {
argValues.push(arg.value);
}
}

return argValues as ResolveOks<PR>;
};
Loading

0 comments on commit 38a845e

Please sign in to comment.