@tempots/std
Version:
Std library for TypeScript. Natural complement to the Tempo libraries.
266 lines (265 loc) • 8.48 kB
JavaScript
import { AsyncResult as c } from "./async-result.js";
const a = {
/**
* Creates a valid `Validation`.
* @returns A `Validation` that is `Valid`.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
valid: { type: "valid" },
/**
* Creates an invalid `Validation`.
* @param error - The error associated with the invalid value.
* @returns A `Validation` that is `Invalid`.
*/
invalid(e) {
return { type: "invalid", error: e };
},
/**
* Checks if a `Validation` is `Valid`.
* @param r - The `Validation` to check.
* @returns `true` if the `Validation` is `Valid`, otherwise `false`.
*/
isValid(e) {
return e.type === "valid";
},
/**
* Checks if a `Validation` is `Invalid`.
* @param r - The `Validation` to check.
* @returns `true` if the `Validation` is `Invalid`, otherwise `false`.
*/
isInvalid(e) {
return e.type === "invalid";
},
/**
* Maps the value of a `Validation` to a new value.
* @param r - The `Validation` to map.
* @param valid - The mapping function for a valid value.
* @param invalid - The mapping function for an invalid value.
* @returns The mapped value.
*/
match: (e, s, r) => a.isValid(e) ? s() : r(e.error),
/**
* Maps the value of a `Validation` to a new `Validation`.
* @param validation - The `Validation` to map.
* @param value - The value to map.
* @returns A new `Validation` with the mapped value.
*/
toResult: (e, s) => a.match(
e,
() => u.success(s),
(r) => u.failure(r)
),
/**
* Execute a function when the `Validation` is valid.
*
* @param r - The `Validation` to check.
* @param apply - The function to execute when the `Validation` is valid.
* @returns The `Validation` object.
*/
whenValid: (e, s) => (a.isValid(e) && s(), e),
/**
* Execute a function when the `Validation` is invalid.
*
* @param r - The `Validation` to check.
* @param apply - The function to execute when the `Validation` is invalid.
* @returns The `Validation` object.
*/
whenInvalid: (e, s) => (a.isInvalid(e) && s(e.error), e)
}, u = {
/**
* Creates a successful `Result`.
* @param value - The value to wrap in a `Success` type.
* @returns A `Result` that is a `Success`.
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
success(e) {
return { type: "Success", value: e };
},
/**
* Creates a failure `Result`.
* @param error - The error to wrap in a `Failure` type.
* @returns A `Result` that is a `Failure`.
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
failure(e) {
return { type: "Failure", error: e };
},
/**
* Maps the value of a `Result` to a new value.
* @param r - The `Result` to map.
* @param f - The mapping function.
* @returns A new `Result` with the mapped value.
* @public
*/
map: (e, s) => e.type === "Success" ? u.success(s(e.value)) : e,
/**
* Maps the value of a `Result` to a new `Result`.
* @param r - The `Result` to map.
* @param f - The mapping function.
* @returns A new `Result` with the mapped value.
* @public
*/
flatMap: (e, s) => e.type === "Success" ? s(e.value) : e,
/**
* Converts a `Result` to an `AsyncResult`.
* @param r - The `Result` to convert.
* @returns An `AsyncResult` that is equivalent to the input `Result`.
* @public
*/
toAsync(e) {
return u.match(
e,
(s) => c.success(s),
(s) => c.failure(s)
);
},
/**
* Converts a `Result` to a `Validation`.
* @param r - The `Result` to convert.
* @returns A `Validation` that is equivalent to the input `Result`.
* @public
*/
toValidation(e) {
return u.match(
e,
() => a.valid,
(s) => a.invalid(s)
);
},
/**
* Checks if a `Result` is a success.
* @param r - The `Result` to check.
* @returns `true` if the `Result` is a `Success`, `false` otherwise.
* @public
*/
isSuccess(e) {
return e.type === "Success";
},
/**
* Checks if a `Result` is a failure.
* @param r - The `Result` to check.
* @returns `true` if the `Result` is a `Failure`, `false` otherwise.
* @public
*/
isFailure(e) {
return e.type === "Failure";
},
/**
* Gets the value of a `Result` if it is a `Success`, otherwise returns the provided default value.
* @param r - The `Result` to get the value from.
* @param alt - The default value to return if the `Result` is a `Failure`.
* @returns The value of the `Result` if it is a `Success`, otherwise the default value.
* @public
*/
getOrElse(e, s) {
return u.isSuccess(e) ? e.value : s;
},
/**
* Gets the value of a `Result` if it is a `Success`, otherwise returns the result of the provided function.
* @param r - The `Result` to get the value from.
* @param altf - The function to call if the `Result` is a `Failure`.
* @returns The value of the `Result` if it is a `Success`, otherwise the result of the function.
* @public
*/
getOrElseLazy(e, s) {
return u.isSuccess(e) ? e.value : s();
},
/**
* Gets the value of a `Result` if it is a `Success`, otherwise returns `null`.
* @param r - The `Result` to get the value from.
* @returns The value of the `Result` if it is a `Success`, otherwise `null`.
* @public
*/
getOrNull(e) {
return u.isSuccess(e) ? e.value : null;
},
/**
* Gets the value of a `Result` if it is a `Success`, otherwise returns `undefined`.
* @param r - The `Result` to get the value from.
* @returns The value of the `Result` if it is a `Success`, otherwise `undefined`.
* @public
*/
getOrUndefined(e) {
return u.isSuccess(e) ? e.value : void 0;
},
/**
* Gets the value of a `Result` if it is a `Success`, otherwise it throws the error contained in the `Failure`.
* @param r - The `Result` to get the value from.
* @returns The value of the `Result` if it is a `Success`.
*/
getUnsafe: (e) => {
if (u.isSuccess(e))
return e.value;
throw e.error;
},
/**
* Based on the state of the result, it picks the appropriate function to call and returns the result.
* @param success - The function to call if the result is a success.
* @param failure - The function to call if the result is a failure.
* @returns The result of calling the appropriate function based on the state of the result.
* @public
*/
match: (e, s, r) => u.isSuccess(e) ? s(e.value) : r(e.error),
/**
* Calls the provided function if the result is a success.
* @param apply - The function to call if the result is a success.
* @returns A function that takes a `Result` and calls the provided function if the result is a success.
* @public
*/
whenSuccess: (e, s) => (u.isSuccess(e) && s(e.value), e),
whenFailure: (e, s) => (u.isFailure(e) && s(e.error), e),
/**
* Combines two results into a single result.
* @param r1 - The first result.
* @param r2 - The second result.
* @param combineV - The function to combine two values.
* @param combineE - The function to combine two errors.
* @returns The combined result.
* @public
*/
combine: (e, s, r, i) => u.match(
e,
(t) => u.match(
s,
(l) => u.success(r(t, l)),
(l) => u.failure(l)
),
(t) => u.match(
s,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(l) => u.failure(t),
(l) => u.failure(i(t, l))
)
),
/**
* Compares two results for equality.
* @param r1 - The first result.
* @param r2 - The second result.
* @param options - The options to use for comparison. By default, uses strict equality.
* @returns `true` if the results are equal, `false` otherwise.
*/
equals: (e, s, r = {
valueEquals: (i, t) => i === t,
errorEquals: (i, t) => i === t
}) => e.type === "Success" && s.type === "Success" ? r.valueEquals(e.value, s.value) : e.type === "Failure" && s.type === "Failure" ? r.errorEquals(e.error, s.error) : !1,
/**
* Combines multiple results into a single result.
* @param results - The results to combine.
* @returns A single result that is a success if all the input results are successes, otherwise a failure.
*/
all: (e) => {
const s = [];
for (const r of e)
if (u.isSuccess(r))
s.push(r.value);
else
return r;
return u.success(s);
}
};
export {
u as R,
a as V
};