Skip to content

Commit

Permalink
fix: resolved /result's issues (#582)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet authored Apr 16, 2023
1 parent f967c25 commit 11f1071
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 158 deletions.
2 changes: 1 addition & 1 deletion packages/result/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"scripts": {
"test": "vitest run",
"lint": "eslint src tests --ext ts --fix -c ../../.eslintrc",
"build": "tsup && tsc -b src",
"build": "tsup",
"docs": "typedoc-json-parser",
"prepack": "yarn build",
"bump": "cliff-jumper",
Expand Down
18 changes: 9 additions & 9 deletions packages/result/src/lib/Option.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { isFunction, type Awaitable } from './common/utils.js';
import { none as _none, None } from './Option/None.js';
import { some as _some, Some } from './Option/Some.js';
import { createNone, OptionNone } from './Option/None.js';
import { createSome, OptionSome } from './Option/Some.js';

export * from './Option/IOption.js';
export type * from './Option/IOption.js';
export * from './Option/OptionError.js';
export { _some as some, _none as none };
export { createSome as some, createNone as none, type OptionNone as None, type OptionSome as Some };

/**
* The union of the two variations of `Option`.
Expand All @@ -23,7 +23,7 @@ export namespace Option {
export function is<T>(value: Option<T>): true;
export function is(value: any): value is Option<unknown>;
export function is(value: any) {
return value instanceof None || value instanceof Some;
return value instanceof OptionNone || value instanceof OptionSome;
}

/**
Expand Down Expand Up @@ -86,11 +86,11 @@ export namespace Option {
return none;
}

export const none = _none;
export const some = _some;
export const none = createNone;
export const some = createSome;

export type Some<T> = import('./Option/Some.js').Some<T>;
export type None = import('./Option/None.js').None;
export type Some<T> = OptionSome<T>;
export type None = OptionNone;

export type UnwrapSome<T extends Option<any>> = T extends Some<infer S> ? S : never;
export type UnwrapSomeArray<T extends readonly Option<any>[] | []> = {
Expand Down
8 changes: 4 additions & 4 deletions packages/result/src/lib/Option/IOption.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Awaitable } from '../common/utils.js';
import type { Option } from '../Option.js';
import type { Result } from '../Result.js';
import type { None } from './None.js';
import type { Some } from './Some.js';
import type { OptionNone } from './None.js';
import type { OptionSome } from './Some.js';

export interface IOption<T> {
/**
Expand All @@ -21,7 +21,7 @@ export interface IOption<T> {
*
* @see {@link https://doc.rust-lang.org/std/option/enum.Option.html#method.is_some}
*/
isSome(): this is Some<T>;
isSome(): this is OptionSome<T>;

/**
* Returns `true` if the option is a `Some` and the value inside of it matches a predicate.
Expand Down Expand Up @@ -63,7 +63,7 @@ export interface IOption<T> {
*
* @see {@link https://doc.rust-lang.org/std/option/enum.Option.html#method.is_none}
*/
isNone(): this is None;
isNone(): this is OptionNone;

/**
* Returns the contained `Some` value.
Expand Down
60 changes: 30 additions & 30 deletions packages/result/src/lib/Option/None.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Awaitable } from '../common/utils.js';
import type { Option } from '../Option.js';
import { err, type Err } from '../Result/Err.js';
import { ok, type Ok } from '../Result/Ok.js';
import { createErr, type ResultErr } from '../Result/Err.js';
import { createOk, type ResultOk } from '../Result/Ok.js';
import type { IOption } from './IOption.js';
import { OptionError } from './OptionError.js';
import type { Some } from './Some.js';
import type { OptionSome } from './Some.js';

export class None implements IOption<any> {
export class OptionNone implements IOption<any> {
public isSome(): false {
return false;
}
Expand All @@ -16,7 +16,7 @@ export class None implements IOption<any> {
return false;
}

public isNone(): this is None {
public isNone(): this is OptionNone {
return true;
}

Expand Down Expand Up @@ -70,12 +70,12 @@ export class None implements IOption<any> {
return Promise.resolve(this);
}

public okOr<E>(error: E): Err<E> {
return err(error);
public okOr<E>(error: E): ResultErr<E> {
return createErr(error);
}

public okOrElse<E>(cb: () => E): Err<E> {
return err(cb());
public okOrElse<E>(cb: () => E): ResultErr<E> {
return createErr(cb());
}

public *iter(): Generator<never> {
Expand All @@ -100,15 +100,15 @@ export class None implements IOption<any> {
return cb();
}

public xor<T>(option: None): None;
public xor<T>(option: Some<T>): Some<T>;
public xor<T>(option: Option<T>): Some<T> | None;
public xor<T>(option: Some<T> | None): Some<T> | None {
public xor<T>(option: OptionNone): OptionNone;
public xor<T>(option: OptionSome<T>): OptionSome<T>;
public xor<T>(option: Option<T>): OptionSome<T> | OptionNone;
public xor<T>(option: OptionSome<T> | OptionNone): OptionSome<T> | OptionNone {
return option.isSome() ? option : this;
}

public filter(predicate: (value: never) => boolean): None;
public filter(): None {
public filter(predicate: (value: never) => boolean): OptionNone;
public filter(): OptionNone {
return this;
}

Expand All @@ -117,41 +117,41 @@ export class None implements IOption<any> {
return false;
}

public zip(other: Option<any>): None;
public zip(): None {
public zip(other: Option<any>): OptionNone;
public zip(): OptionNone {
return this;
}

public zipWith(other: Option<any>, f: (s: never, o: never) => any): None;
public zipWith(): None {
public zipWith(other: Option<any>, f: (s: never, o: never) => any): OptionNone;
public zipWith(): OptionNone {
return this;
}

public unzip(): [None, None] {
public unzip(): [OptionNone, OptionNone] {
return [this, this];
}

public transpose(): Ok<None> {
return ok(this);
public transpose(): ResultOk<OptionNone> {
return createOk(this);
}

public flatten(): None {
public flatten(): OptionNone {
return this;
}

public intoPromise(): Promise<None> {
return Promise.resolve(none);
public intoPromise(): Promise<OptionNone> {
return Promise.resolve(createNone);
}

public eq(other: None): true;
public eq(other: Some<any>): false;
public eq(other: OptionNone): true;
public eq(other: OptionSome<any>): false;
public eq(other: Option<any>): boolean;
public eq(other: Option<any>): boolean {
return other.isNone();
}

public ne(other: None): false;
public ne(other: Some<any>): true;
public ne(other: OptionNone): false;
public ne(other: OptionSome<any>): true;
public ne(other: Option<any>): boolean;
public ne(other: Option<any>): boolean {
return other.isSome();
Expand All @@ -166,4 +166,4 @@ export class None implements IOption<any> {
}
}

export const none = new None();
export const createNone = new OptionNone();
82 changes: 41 additions & 41 deletions packages/result/src/lib/Option/Some.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import type { Awaitable } from '../common/utils.js';
import type { Option } from '../Option.js';
import type { Result } from '../Result.js';
import { err, type Err } from '../Result/Err.js';
import { ok, type Ok } from '../Result/Ok.js';
import { createErr, type ResultErr } from '../Result/Err.js';
import { createOk, type ResultOk } from '../Result/Ok.js';
import type { IOption } from './IOption.js';
import { none, type None } from './None.js';
import { createNone, type OptionNone } from './None.js';

export class Some<T> implements IOption<T> {
export class OptionSome<T> implements IOption<T> {
private readonly value: T;

public constructor(value: T) {
this.value = value;
}

public isSome(): this is Some<T> {
public isSome(): this is OptionSome<T> {
return true;
}

Expand Down Expand Up @@ -44,8 +44,8 @@ export class Some<T> implements IOption<T> {
return this.value;
}

public map<U>(cb: (value: T) => U): Some<U> {
return some(cb(this.value));
public map<U>(cb: (value: T) => U): OptionSome<U> {
return createSome(cb(this.value));
}

public mapInto<R extends Option<any>>(cb: (value: T) => R): R {
Expand Down Expand Up @@ -75,14 +75,14 @@ export class Some<T> implements IOption<T> {
return this;
}

public okOr(err?: any): Ok<T>;
public okOr(): Ok<T> {
return ok(this.value);
public okOr(err?: any): ResultOk<T>;
public okOr(): ResultOk<T> {
return createOk(this.value);
}

public okOrElse(cb: () => any): Ok<T>;
public okOrElse(): Ok<T> {
return ok(this.value);
public okOrElse(cb: () => any): ResultOk<T>;
public okOrElse(): ResultOk<T> {
return createOk(this.value);
}

public *iter(): Generator<T> {
Expand All @@ -107,68 +107,68 @@ export class Some<T> implements IOption<T> {
return this;
}

public xor(option: Some<T>): None;
public xor(option: None): this;
public xor(option: Option<T>): this | None;
public xor(option: Option<T>): this | None {
return option.isSome() ? none : this;
public xor(option: OptionSome<T>): OptionNone;
public xor(option: OptionNone): this;
public xor(option: Option<T>): this | OptionNone;
public xor(option: Option<T>): this | OptionNone {
return option.isSome() ? createNone : this;
}

public filter(predicate: (value: T) => true): this;
public filter(predicate: (value: T) => false): None;
public filter(predicate: (value: T) => boolean): this | None;
public filter(predicate: (value: T) => boolean): this | None {
return predicate(this.value) ? this : none;
public filter(predicate: (value: T) => false): OptionNone;
public filter(predicate: (value: T) => boolean): this | OptionNone;
public filter(predicate: (value: T) => boolean): this | OptionNone {
return predicate(this.value) ? this : createNone;
}

public contains(value: T): boolean {
return this.value === value;
}

public zip(other: None): None;
public zip<U>(other: Some<U>): Some<[T, U]>;
public zip(other: OptionNone): OptionNone;
public zip<U>(other: OptionSome<U>): OptionSome<[T, U]>;
public zip<U>(other: Option<U>): Option<[T, U]>;
public zip<U>(other: Option<U>): Option<[T, U]> {
return other.map((o) => [this.value, o] as [T, U]);
}

public zipWith<U, R>(other: None, f: (s: T, o: U) => R): None;
public zipWith<U, R>(other: Some<U>, f: (s: T, o: U) => R): Some<R>;
public zipWith<U, R>(other: OptionNone, f: (s: T, o: U) => R): OptionNone;
public zipWith<U, R>(other: OptionSome<U>, f: (s: T, o: U) => R): OptionSome<R>;
public zipWith<U, R>(other: Option<U>, f: (s: T, o: U) => R): Option<R>;
public zipWith<U, R>(other: Option<U>, f: (s: T, o: U) => R): Option<R> {
return other.map((o) => f(this.value, o));
}

public unzip<I, U>(this: Some<readonly [I, U]>): [Some<I>, Some<U>] {
public unzip<I, U>(this: OptionSome<readonly [I, U]>): [OptionSome<I>, OptionSome<U>] {
const [s, o] = this.value;
return [some(s), some(o)];
return [createSome(s), createSome(o)];
}

public transpose<Inner>(this: Some<Ok<Inner>>): Ok<Some<Inner>>;
public transpose<Inner>(this: Some<Err<Inner>>): Err<Some<Inner>>;
public transpose<IT, E>(this: Some<Result<IT, E>>): Result<Some<IT>, E>;
public transpose<IT, E>(this: Some<Result<IT, E>>): Result<Some<IT>, E> {
public transpose<Inner>(this: OptionSome<ResultOk<Inner>>): ResultOk<OptionSome<Inner>>;
public transpose<Inner>(this: OptionSome<ResultErr<Inner>>): ResultErr<OptionSome<Inner>>;
public transpose<IT, E>(this: OptionSome<Result<IT, E>>): Result<OptionSome<IT>, E>;
public transpose<IT, E>(this: OptionSome<Result<IT, E>>): Result<OptionSome<IT>, E> {
return this.value.match({
ok: (v) => ok(some(v)),
err: (e) => err(e)
ok: (v) => createOk(createSome(v)),
err: (e) => createErr(e)
});
}

public flatten<Inner extends Option<any>>(this: Some<Inner>): Inner {
public flatten<Inner extends Option<any>>(this: OptionSome<Inner>): Inner {
return this.value;
}

public async intoPromise(): Promise<Some<Awaited<T>>> {
return some(await this.value);
public async intoPromise(): Promise<OptionSome<Awaited<T>>> {
return createSome(await this.value);
}

public eq(other: None): false;
public eq(other: OptionNone): false;
public eq(other: Option<T>): boolean;
public eq(other: Option<T>): boolean {
return other.isSomeAnd((value) => this.value === value);
}

public ne(other: None): true;
public ne(other: OptionNone): true;
public ne(other: Option<T>): boolean;
public ne(other: Option<T>): boolean {
return !this.eq(other);
Expand All @@ -183,6 +183,6 @@ export class Some<T> implements IOption<T> {
}
}

export function some<T>(value: T): Some<T> {
return new Some<T>(value);
export function createSome<T>(value: T): OptionSome<T> {
return new OptionSome<T>(value);
}
Loading

0 comments on commit 11f1071

Please sign in to comment.