Created
February 4, 2021 17:51
-
-
Save aleics/0a7d09cc00156584b4ac7641b0f1a266 to your computer and use it in GitHub Desktop.
Rust Result in Typescript 🦀
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Cases<O, T, E, R> { | |
ok: (value: O) => T; | |
err: (value: E) => R; | |
} | |
export abstract class Result<O, E> { | |
public abstract isOk(): boolean; | |
public abstract isErr(): boolean; | |
public abstract match<T, R>(cases: Cases<O, T, E, R>): T | R; | |
public abstract map<T>(fn: (value: O) => T): Result<T, E>; | |
public abstract mapErr<T>(fn: (value: E) => T): Result<O, T>; | |
public abstract and<T>(result: Result<T, E>): Result<T, E>; | |
public abstract andThen<T>(fn: (value: O) => Result<T, E>): Result<T, E>; | |
public abstract or<R>(result: Result<O, R>): Result<O, R>; | |
public abstract orElse<R>(fn: (value: E) => Result<O, R>): Result<O, R>; | |
} | |
class OkResult<O, E> extends Result<O, E> { | |
private value: O; | |
private constructor(value: O) { | |
super(); | |
this.value = value; | |
} | |
static of<O, E>(value: O): OkResult<O, E> { | |
return new OkResult(value); | |
} | |
isOk(): boolean { | |
return true; | |
} | |
isErr(): boolean { | |
return false; | |
} | |
match<T, R>(cases: Cases<O, T, E, R>): T { | |
return cases.ok(this.value); | |
} | |
map<T>(fn: (value: O) => T): Result<T, E> { | |
return OkResult.of(fn(this.value)); | |
} | |
mapErr<T>(_fn: (value: E) => T): Result<O, T> { | |
return OkResult.of(this.value); | |
} | |
and<T>(result: Result<T, E>): Result<T, E> { | |
return result; | |
} | |
andThen<T>(fn: (value: O) => Result<T, E>): Result<T, E> { | |
return fn(this.value); | |
} | |
or<R>(_result: Result<O, R>): Result<O, R> { | |
return OkResult.of(this.value); | |
} | |
orElse<R>(_fn: (value: E) => Result<O, R>): Result<O, R> { | |
return OkResult.of(this.value); | |
} | |
} | |
class ErrResult<O, E> extends Result<O, E> { | |
private value: E; | |
private constructor(value: E) { | |
super(); | |
this.value = value; | |
} | |
static of<O, E>(value: E): ErrResult<O, E> { | |
return new ErrResult(value); | |
} | |
isOk(): boolean { | |
return false; | |
} | |
isErr(): boolean { | |
return true; | |
} | |
match<T, R>(cases: Cases<O, T, E, R>): R { | |
return cases.err(this.value); | |
} | |
map<T>(_fn: (value: O) => T): Result<T, E> { | |
return ErrResult.of(this.value); | |
} | |
mapErr<T>(fn: (value: E) => T): Result<O, T> { | |
return ErrResult.of(fn(this.value)); | |
} | |
and<T>(_result: Result<T, E>): Result<T, E> { | |
return ErrResult.of(this.value); | |
} | |
andThen<T>(_fn: (value: O) => Result<T, E>): Result<T, E> { | |
return ErrResult.of(this.value); | |
} | |
or<R>(result: Result<O, R>): Result<O, R> { | |
return result; | |
} | |
orElse<R>(fn: (value: E) => Result<O, R>): Result<O, R> { | |
return fn(this.value); | |
} | |
} | |
export function Err<O, E>(value: E): Result<O, E> { | |
return ErrResult.of(value); | |
} | |
export function Ok<O, E>(value: O): Result<O, E> { | |
return OkResult.of(value); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment