Skip to content

Commit

Permalink
Option docs and some brushing
Browse files Browse the repository at this point in the history
  • Loading branch information
a coder committed Mar 10, 2023
1 parent aace3f2 commit 16b09d2
Show file tree
Hide file tree
Showing 36 changed files with 529 additions and 59 deletions.
4 changes: 2 additions & 2 deletions dist/option/api/format.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { OptionUnion } from "../interfaces";
export declare function format<T>(option: OptionUnion<T>): string;
import { Option } from "../interfaces";
export declare function format<T>(option: Option<T>, fn?: (option: Option<T>) => string): string;
//# sourceMappingURL=format.d.ts.map
2 changes: 1 addition & 1 deletion dist/option/api/format.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions dist/option/api/format.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export function format(option) {
return option.type === "Some" ? `Some(${option.value})` : `None`;
export function format(option, fn) {
const inner = option.inner();
return inner.type === "Some"
? `Some(${fn?.(option) ?? inner.value})`
: `None`;
}
3 changes: 3 additions & 0 deletions dist/option/api/isNoneAnd.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Option } from "../interfaces";
export declare function isNoneAnd<T>(option: Option<T>, fn: () => boolean): boolean;
//# sourceMappingURL=isNoneAnd.d.ts.map
1 change: 1 addition & 0 deletions dist/option/api/isNoneAnd.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions dist/option/api/isNoneAnd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isNoneAnd(option, fn) {
return option.isNone() && fn();
}
4 changes: 2 additions & 2 deletions dist/option/api/map.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { OptionUnion } from "../interfaces";
export declare function map<T, U>(option: OptionUnion<T>, fn: (value: T) => U): OptionUnion<U>;
import { Option, OptionUnion } from "../interfaces";
export declare function map<T, U>(option: Option<T>, fn: (value: T) => U): OptionUnion<U>;
//# sourceMappingURL=map.d.ts.map
2 changes: 1 addition & 1 deletion dist/option/api/map.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion dist/option/api/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { unionNone } from "./unionNone";
import { unionSome } from "./unionSome";
import { unwrap } from "./unwrap";
export function map(option, fn) {
if (option.type === "Some") {
const inner = option.inner();
if (inner.type === "Some") {
return unionSome(fn(unwrap(option)));
}
return unionNone();
Expand Down
4 changes: 2 additions & 2 deletions dist/option/api/unwrap.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { OptionUnion } from "../interfaces";
export declare function unwrap<T>(option: OptionUnion<T>): T;
import { Option } from "../interfaces";
export declare function unwrap<T>(option: Option<T>): T;
//# sourceMappingURL=unwrap.d.ts.map
2 changes: 1 addition & 1 deletion dist/option/api/unwrap.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions dist/option/api/unwrap.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { format } from "./format";
export function unwrap(option) {
if (option.type === "None") {
const inner = option.inner();
if (inner.type === "None") {
throw new Error(`unwrap called on ${format(option)}`);
}
return option.value;
return inner.value;
}
2 changes: 1 addition & 1 deletion dist/option/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions dist/option/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ import { format } from "./api/format";
import { unionNone } from "./api/unionNone";
import { unionSome } from "./api/unionSome";
import { filter } from "./api/filter";
import { isNoneAnd } from "./api/isNoneAnd";
export function createOption(v) {
let inner = v;
const api = {
inner: () => inner,
eq: (value, by) => eq(api, value, by),
format: () => format(inner),
format: (formatter) => format(api, formatter),
clone: () => createOption(clone(inner)),
unwrap: () => unwrap(inner),
unwrap: () => unwrap(api),
unwrapOr: (default_value) => unwrapOr(inner, default_value),
isNone: () => isNone(inner),
isSome: () => isSome(inner),
take: () => createOption(take(inner)),
isSomeAnd: (fn) => isSomeAnd(api, fn),
map: (fn) => createOption(map(inner, fn)),
isNoneAnd: (fn) => isNoneAnd(api, fn),
map: (fn) => createOption(map(api, fn)),
or: (new_value) => createOption(or(api, new_value)),
orElse: (fn) => createOption(orElse(api, fn)),
and: (new_value) => createOption(and(api, new_value)),
Expand Down
195 changes: 193 additions & 2 deletions dist/option/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,213 @@ export interface None {
}
export type OptionUnion<T> = None | Some<T>;
export interface Option<T> {
/**
* Extract internals as union. Useful when you want to handle option yourself
* # Example
* ```ts
* const option = Some(3).inner();
* if (option.type === "Some") {
* option.value // number
* }
* ```
*/
inner(): OptionUnion<T>;
/**
* Compare two `Option`'s to each other
* # Example
* ```ts
* Some(3).eq(Some(3)) // true
* Some(3).eq(Some(4)) // false
* Some(3).eq(None()) // false
* ```
*/
eq<U>(v: Option<T>, by?: (item: T) => U): boolean;
format(): string;
/**
* Just a simple data formatter
* # Example
* ```ts
* Some(3).format() // `Some(3)`
*
* // or if you want to format your value yourself
* Some({ x: 3 }).format((v) => JSON.stringify(v.inner().value, null, 2))
* ```
*/
format(formatter?: (result: Option<T>) => string): string;
/** Clone option internal state
* # Example
* ```ts
* // Imagine we mutating Option's inner state
* const maybeString = Some("data"); // Some("data")
* const takenString = maybeString.take(); // Some("data")
* maybeString.isNone() // true
* // In order to save maybeString inner state we have to clone it
* const maybeString = Some("data"); // Some("data")
* const takenString = maybeString.clone().take(); // Some("data")
* maybeString.isSome() // true
* ```
*/
clone(): Option<T>;
/**
* Returns the contained `Some` value. It is preferred to use other methods rather than using `unwrap`
*
* But it's usefull for quick prototyping or when you know type inside
*
* # Throws
* When value is `None`
* # Example
* ```ts
* Some(3).unwrap() // 3
* None().unwrap() // throw Error
* ```
*/
unwrap(): T;
/**
* Returns the contained `Some` or default value
* # Example
* ```ts
* Some(3).unwrapOr(4) // 3
* None().unwrapOr(4) // 4
* ```
*/
unwrapOr(v: T): T;
/**
* Returns `true` if value is `None`
* # Example
* ```ts
* Some(3).isNone() // false
* None().isNone() // true
* ```
*/
isNone(): boolean;
/**
* Returns `true` if value is `Some`
* # Example
* ```ts
* Some(3).isSome() // true
* None().isSome() // false
* ```
*/
isSome(): boolean;
/**
* Takes the value out of the option, leaving a `None` in its place.
*
* # Example
* ```ts
* const maybeString = Some("data"); // Some("data")
* const takenString = maybeString.take(); // Some("data")
* maybeString.isNone() // true
* ```
*/
take(): Option<T>;
/**
* Returns `true` if value `Some` and predicate `fn` returns `true`.
*
* # Example
* ```ts
* Some(3).isSomeAnd(v => v === 3) // true
* Some(3).isSomeAnd(v => v === 4) // false
* None().isSomeAnd(v => true) // false
* ```
*/
isSomeAnd(fn: (v: T) => boolean): boolean;
/**
* Returns `true` if value `Some` and predicate `fn` returns `true`.
*
* # Example
* ```ts
* Some(3).isNoneAnd(v => true) // false
* None().isNoneAnd(v => true) // true
* None().isNoneAnd(v => false) // false
* ```
*/
isNoneAnd(fn: () => boolean): boolean;
/**
* Changes contained value if `Some` by applying `fn` to previous `Some`.
*
* # Example
* ```ts
* Some(3).map(v => "value") // Some("value")
* None().map(v => "value") // None()
* ```
*/
map<U>(fn: (v: T) => U): Option<U>;
or(v: Option<T>): Option<T>;
/**
* Returns `option` if the result is `None`, otherwise returns the `Some` value.
*
* This function can be used for control flow based on `Option` values.
* # Example
* ```ts
* Some(3).or(Some(6)) // Some(3)
* None().or(Some(6)) // Some(6)
* None().or(None()) // None()
* ```
*/
or(option: Option<T>): Option<T>;
/**
* Calls `fn` if the result is `None`, otherwise returns the `Some` value.
*
* This function can be used for control flow based on `Option` values.
* # Example
* ```ts
* Some(3).orElse(() => Some(6)) // Some(3)
* None().orElse(() => Some(6)) // Some(6)
* None().orElse(() => None()) // None()
* ```
*/
orElse(fn: () => Option<T>): Option<T>;
/**
* Returns `option` if the result is `Some`, otherwise returns the `None`.
*
* This function can be used for control flow based on `Option` values.
* # Example
* ```ts
* Some(3).and(Some(6)) // Some(6)
* Some(3).and(None()) // None()
* None().and(Some(6)) // None()
* ```
*/
and<U>(v: Option<U>): Option<U>;
/**
* Calls `fn` if the result is `Some`, otherwise returns the `None`.
*
* This function can be used for control flow based on `Option` values.
* # Example
* ```ts
* Some(3).andThen(() => Some(6)) // Some(6)
* Some(3).andThen(() => None()) // None()
* None().andThen(() => Some(6)) // None()
* ```
*/
andThen<U>(fn: (v: T) => Option<U>): Option<U>;
/**
* Convert `Option<T>` to `Result<T, E>` with provided default `Err` if value is `None`
* # Example
* ```ts
* const withString = Some("data");
* const withoutString = None<string>();
*
* withString.result(() => "Not a string!") // Ok("data")
* withoutString.result(() => "Not a string!") // Err("Not a string!")
* ```
*/
result<E>(noneErr: () => E): Result<T, E>;
/**
* Returns `None` if the option is `None`, otherwise calls predicate with the wrapped value and returns:
*
* - `Some(t)` if predicate returns `true` (where `t` is the wrapped value)
* - `None` if predicate returns `false`.
*
* This function works similar to `Iter.filter()`. You can imagine the `Option<T>` being an iterator over one or zero elements. `filter()` lets you decide which elements to keep.
*
* # Example
* ```ts
* const data = Some("coolvalue");
* const CoolData = data.filter(v => v.includes("cool"))
* assert(CoolData, Some("coolvalue"))
* const boringData = data.filter(v => v.includes("boring"))
* assert(boringData, None())
* ```
*/
filter(fn: (item: T) => boolean): Option<T>;
}
//# sourceMappingURL=interfaces.d.ts.map
2 changes: 1 addition & 1 deletion dist/option/interfaces.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/result/api/format.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { ResultUnion } from "../interfaces";
export declare function format<T, E>(result: ResultUnion<T, E>): string;
import { Result } from "../interfaces";
export declare function format<T, E>(result: Result<T, E>, formatter?: (result: Result<T, E>) => string): string;
//# sourceMappingURL=format.d.ts.map
2 changes: 1 addition & 1 deletion dist/result/api/format.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions dist/result/api/format.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export function format(result) {
return `Result.${result.type}(${result.value})`;
export function format(result, formatter) {
const inner = result.inner();
return `Result.${inner.type}(${formatter?.(result) ?? inner.value})`;
}
2 changes: 1 addition & 1 deletion dist/result/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function createResult(result) {
const api = {
inner: () => result,
eq: (other) => eq(api, other),
format: () => format(result),
format: (formatter) => format(api, formatter),
isOk: () => isOk(result),
isErr: () => isErr(result),
unwrap: () => unwrap(api),
Expand Down
4 changes: 2 additions & 2 deletions dist/result/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export interface Result<T, Err> {
* Just a simple data formatter
* # Example
* ```ts
* Ok(3).format() === `Result.Ok(3)`
* Ok(3).format() // `Result.Ok(3)`
*
* // or if you want to format your value yourself
* Err({ x: 3 }).format((v) => JSON.stringify(v.inner().value, null, 2))
* ```
*/
format(fn?: (result: Result<T, Err>) => string): string;
format(formatter?: (result: Result<T, Err>) => string): string;
/**
* Compare two `Result`'s to each other
* # Example
Expand Down
Loading

0 comments on commit 16b09d2

Please sign in to comment.