mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
48e0c70292
ghstack-source-id: bb66913e2d3c814696311371ed655f3da03d1199 Pull Request resolved: https://github.com/facebook/react-forget/pull/2926
237 lines
6.1 KiB
TypeScript
237 lines
6.1 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
// Direct translation of Rust's Result type, although some ownership related methods are omitted.
|
|
export interface Result<T, E> {
|
|
/*
|
|
* Maps a `Result<T, E>` to `Result<U, E>` by applying a function to a contained `Ok` value,
|
|
* leaving an `Err` value untouched.
|
|
*
|
|
* This function can be used to compose the results of two functions.
|
|
*/
|
|
map<U>(fn: (val: T) => U): Result<U, E>;
|
|
/*
|
|
* Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a contained `Err` value,
|
|
* leaving an `Ok` value untouched.
|
|
*
|
|
* This function can be used to pass through a successful result while handling an error.
|
|
*/
|
|
mapErr<F>(fn: (val: E) => F): Result<T, F>;
|
|
/*
|
|
* Returns the provided default (if `Err`), or applies a function to the contained value
|
|
* (if `Ok`).
|
|
*
|
|
* Arguments passed to {@link mapOr} are eagerly evaluated; if you are passing the result of a
|
|
* function call, it is recommended to use {@link mapOrElse}, which is lazily evaluated.
|
|
*/
|
|
mapOr<U>(fallback: U, fn: (val: T) => U): U;
|
|
/*
|
|
* Maps a `Result<T, E>` to `U` by applying fallback function default to a contained `Err` value,
|
|
* or function `fn` to a contained `Ok` value.
|
|
*
|
|
* This function can be used to unpack a successful result while handling an error.
|
|
*/
|
|
mapOrElse<U>(fallback: () => U, fn: (val: T) => U): U;
|
|
/*
|
|
* Calls `fn` if the result is `Ok`, otherwise returns the `Err` value of self.
|
|
*
|
|
* This function can be used for control flow based on Result values.
|
|
*/
|
|
andThen<U>(fn: (val: T) => Result<U, E>): Result<U, E>;
|
|
/*
|
|
* Returns res if the result is `Ok`, otherwise returns the `Err` value of self.
|
|
*
|
|
* Arguments passed to {@link and} are eagerly evaluated; if you are passing the result of a
|
|
* function call, it is recommended to use {@link andThen}, which is lazily evaluated.
|
|
*/
|
|
and<U>(res: Result<U, E>): Result<U, E>;
|
|
/*
|
|
* Returns `res` if the result is `Err`, otherwise returns the `Ok` value of self.
|
|
*
|
|
* Arguments passed to {@link or} are eagerly evaluated; if you are passing the result of a
|
|
* function call, it is recommended to use {@link orElse}, which is lazily evaluated.
|
|
*/
|
|
or(res: Result<T, E>): Result<T, E>;
|
|
/*
|
|
* Calls `fn` if the result is `Err`, otherwise returns the `Ok` value of self.
|
|
*
|
|
* This function can be used for control flow based on result values.
|
|
*/
|
|
orElse<F>(fn: (val: E) => Result<T, F>): Result<T, F>;
|
|
// Returns `true` if the result is `Ok`.
|
|
isOk(): this is OkImpl<T>;
|
|
// Returns `true` if the result is `Err`.
|
|
isErr(): this is ErrImpl<E>;
|
|
// Returns the contained `Ok` value or throws.
|
|
expect(msg: string): T;
|
|
// Returns the contained `Err` value or throws.
|
|
expectErr(msg: string): E;
|
|
// Returns the contained `Ok` value.
|
|
unwrap(): T;
|
|
/*
|
|
* Returns the contained `Ok` value or a provided default.
|
|
*
|
|
* Arguments passed to {@link unwrapOr} are eagerly evaluated; if you are passing the result of a
|
|
* function call, it is recommended to use {@link unwrapOrElse}, which is lazily evaluated.
|
|
*/
|
|
unwrapOr(fallback: T): T;
|
|
// Returns the contained `Ok` value or computes it from a closure.
|
|
unwrapOrElse(fallback: (val: E) => T): T;
|
|
// Returns the contained `Err` value or throws.
|
|
unwrapErr(): E;
|
|
}
|
|
|
|
export function Ok<T>(val: T): OkImpl<T> {
|
|
return new OkImpl(val);
|
|
}
|
|
|
|
class OkImpl<T> implements Result<T, never> {
|
|
constructor(private val: T) {}
|
|
|
|
map<U>(fn: (val: T) => U): Result<U, never> {
|
|
return new OkImpl(fn(this.val));
|
|
}
|
|
|
|
mapErr<F>(_fn: (val: never) => F): Result<T, F> {
|
|
return this;
|
|
}
|
|
|
|
mapOr<U>(_fallback: U, fn: (val: T) => U): U {
|
|
return fn(this.val);
|
|
}
|
|
|
|
mapOrElse<U>(_fallback: () => U, fn: (val: T) => U): U {
|
|
return fn(this.val);
|
|
}
|
|
|
|
andThen<U>(fn: (val: T) => Result<U, never>): Result<U, never> {
|
|
return fn(this.val);
|
|
}
|
|
|
|
and<U>(res: Result<U, never>): Result<U, never> {
|
|
return res;
|
|
}
|
|
|
|
or(_res: Result<T, never>): Result<T, never> {
|
|
return this;
|
|
}
|
|
|
|
orElse<F>(_fn: (val: never) => Result<T, F>): Result<T, F> {
|
|
return this;
|
|
}
|
|
|
|
isOk(): boolean {
|
|
return true;
|
|
}
|
|
|
|
isErr(): boolean {
|
|
return false;
|
|
}
|
|
|
|
expect(_msg: string): T {
|
|
return this.val;
|
|
}
|
|
|
|
expectErr(msg: string): never {
|
|
throw new Error(`${msg}: ${this.val}`);
|
|
}
|
|
|
|
unwrap(): T {
|
|
return this.val;
|
|
}
|
|
|
|
unwrapOr(_fallback: T): T {
|
|
return this.val;
|
|
}
|
|
|
|
unwrapOrElse(_fallback: (val: never) => T): T {
|
|
return this.val;
|
|
}
|
|
|
|
unwrapErr(): never {
|
|
if (this.val instanceof Error) {
|
|
throw this.val;
|
|
}
|
|
throw new Error(`Can't unwrap \`Ok\` to \`Err\`: ${this.val}`);
|
|
}
|
|
}
|
|
|
|
export function Err<E>(val: E): ErrImpl<E> {
|
|
return new ErrImpl(val);
|
|
}
|
|
|
|
class ErrImpl<E> implements Result<never, E> {
|
|
constructor(private val: E) {}
|
|
|
|
map<U>(_fn: (val: never) => U): Result<U, E> {
|
|
return this;
|
|
}
|
|
|
|
mapErr<F>(fn: (val: E) => F): Result<never, F> {
|
|
return new ErrImpl(fn(this.val));
|
|
}
|
|
|
|
mapOr<U>(fallback: U, _fn: (val: never) => U): U {
|
|
return fallback;
|
|
}
|
|
|
|
mapOrElse<U>(fallback: () => U, _fn: (val: never) => U): U {
|
|
return fallback();
|
|
}
|
|
|
|
andThen<U>(_fn: (val: never) => Result<U, E>): Result<U, E> {
|
|
return this;
|
|
}
|
|
|
|
and<U>(_res: Result<U, E>): Result<U, E> {
|
|
return this;
|
|
}
|
|
|
|
or(res: Result<never, E>): Result<never, E> {
|
|
return res;
|
|
}
|
|
|
|
orElse<F>(fn: (val: E) => ErrImpl<F>): Result<never, F> {
|
|
return fn(this.val);
|
|
}
|
|
|
|
isOk(): boolean {
|
|
return false;
|
|
}
|
|
|
|
isErr(): boolean {
|
|
return true;
|
|
}
|
|
|
|
expect(msg: string): never {
|
|
throw new Error(`${msg}: ${this.val}`);
|
|
}
|
|
|
|
expectErr(_msg: string): E {
|
|
return this.val;
|
|
}
|
|
|
|
unwrap(): never {
|
|
if (this.val instanceof Error) {
|
|
throw this.val;
|
|
}
|
|
throw new Error(`Can't unwrap \`Err\` to \`Ok\`: ${this.val}`);
|
|
}
|
|
|
|
unwrapOr<T>(fallback: T): T {
|
|
return fallback;
|
|
}
|
|
|
|
unwrapOrElse<T>(fallback: (val: E) => T): T {
|
|
return fallback(this.val);
|
|
}
|
|
|
|
unwrapErr(): E {
|
|
return this.val;
|
|
}
|
|
}
|