ts-results-es
Version:
A TypeScript implementation of Rust's Result and Option objects.
230 lines • 6.68 kB
JavaScript
import { of } from 'rxjs';
import { filter, map, mergeMap, switchMap, tap } from 'rxjs/operators';
import { Ok, Result } from '../index.js';
/**
* Allows you to do the same actions as the normal rxjs `map` operator on a stream of Result objects.
*
* @example
* ```typescript
* import { of, Observable } from 'rxjs';
* import { Ok, Err, Result } from 'ts-results-es';
* import { resultMap } from 'ts-results-es/rxjs-operators';
*
* const obs$: Observable<Result<number, Error>> = of(Ok(5), Err('uh oh'));
*
* const greaterThanZero = obs$.pipe(
* resultMap((number) => number > 0), // Return true for values greater zero
* ); // Has type Observable<Result<boolean, 'uh oh'>>
*
* greaterThanZero.subscribe((result) => {
* if (result.isOk()) {
* console.log('Was greater than zero: ' + result.value);
* } else {
* console.log('Got Error Message: ' + result.error);
* }
* });
*
* // Logs the following:
* // Was greater than zero: true
* // Got Error Message: uh oh
* ```
*/
export function resultMap(mapper) {
return function (source) {
return source.pipe(map(function (result) { return result.map(mapper); }));
};
}
/**
* Behaves exactly the same as `resultMap`, but maps the error value.
*/
export function resultMapErr(mapper) {
return function (source) {
return source.pipe(map(function (result) { return result.mapErr(mapper); }));
};
}
/**
* Behaves the same as `resultMap`, but takes a value instead of a function.
*/
export function resultMapTo(value) {
return function (source) {
return source.pipe(map(function (result) { return result.map(function () { return value; }); }));
};
}
/**
* Behaves the same as `resultMapErr`, but takes a value instead of a function.
*/
export function resultMapErrTo(value) {
return function (source) {
return source.pipe(map(function (result) { return result.mapErr(function () { return value; }); }));
};
}
/**
* Allows you to turn a stream of Result objects into a stream of values,
* transforming any errors into a value.
*
* Similar to calling the `else` function, but works on a stream of Result objects.
*
* @example
* ```typescript
* import { of, Observable } from 'rxjs';
* import { Ok, Err, Result } from 'ts-results-es';
* import { elseMap } from 'ts-results-es/rxjs-operators';
*
* const obs$: Observable<Result<number, Error>> = of(Ok(5), Err(new Error('uh oh')));
*
* const doubled = obs$.pipe(
* elseMap((err) => {
* console.log('Got error: ' + err.message);
*
* return -1;
* }),
* ); // Has type Observable<number>
*
* doubled.subscribe((number) => {
* console.log('Got number: ' + number);
* });
*
* // Logs the following:
* // Got number: 5
* // Got error: uh oh
* // Got number: -1
* ```
*/
export function elseMap(mapper) {
return function (source) {
return source.pipe(map(function (result) {
if (result.isErr()) {
return mapper(result.error);
}
else {
return result.value;
}
}));
};
}
/**
* Behaves the same as `elseMap`, but takes a value instead of a function.
*/
export function elseMapTo(value) {
return function (source) {
return source.pipe(map(function (result) {
if (result.isErr()) {
return value;
}
else {
return result.value;
}
}));
};
}
export function resultSwitchMap(mapper) {
return function (source) {
return source.pipe(switchMap(function (result) {
if (result.isOk()) {
return mapper(result.value);
}
else {
return of(result);
}
}), map(function (result) {
if (Result.isResult(result)) {
return result;
}
else {
return new Ok(result);
}
}));
};
}
export function resultMergeMap(mapper) {
return function (source) {
return source.pipe(mergeMap(function (result) {
if (result.isOk()) {
return mapper(result.value);
}
else {
return of(result);
}
}), map(function (result) {
if (Result.isResult(result)) {
return result;
}
else {
return new Ok(result);
}
}));
};
}
/**
* Converts an `Observable<Result<T, E>>` to an `Observable<T>` by
* filtering out the Errs and mapping to the Ok values.
*
* @example
* ```typescript
* import { of, Observable } from 'rxjs';
* import { Ok, Err, Result } from 'ts-results-es';
* import { filterResultOk } from 'ts-results-es/rxjs-operators';
*
* const obs$: Observable<Result<number, Error>> = of(new Ok(5), new Err(new Error('uh oh')));
*
* const test$ = obs$.pipe(filterResultOk()); // Has type Observable<number>
*
* test$.subscribe((result) => {
* console.log('Got number: ' + result);
* });
*
* // Logs the following:
* // Got number: 5
* ```
*/
export function filterResultOk() {
return function (source) {
return source.pipe(filter(function (result) { return result.isOk(); }), map(function (result) { return result.value; }));
};
}
/**
* Converts an `Observable<Result<T, E>>` to an `Observable<E>` by
* filtering out the Oks and mapping to the error values.
*
* @example
* ```typescript
* import { of, Observable } from 'rxjs';
* import { Ok, Err, Result } from 'ts-results-es';
* import { filterResultErr } from 'ts-results-es/rxjs-operators';
*
* const obs$: Observable<Result<number, Error>> = of(new Ok(5), new Err(new Error('uh oh')));
*
* const test$ = obs$.pipe(filterResultErr()); // Has type Observable<Error>
*
* test$.subscribe((result) => {
* console.log('Got error: ' + result);
* });
*
* // Logs the following:
* // Got error: uh oh
* ```
*/
export function filterResultErr() {
return function (source) {
return source.pipe(filter(function (result) { return result.isErr(); }), map(function (result) { return result.error; }));
};
}
export function tapResultErr(tapFn) {
return function (source) {
return source.pipe(tap(function (r) {
if (!r.isOk()) {
tapFn(r.error);
}
}));
};
}
export function tapResultOk(tapFn) {
return function (source) {
return source.pipe(tap(function (r) {
if (r.isOk()) {
tapFn(r.value);
}
}));
};
}
//# sourceMappingURL=index.js.map