From ab53f080b2cbf8a4e6ce3e9e4394684e38459fc8 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Wed, 5 Jul 2023 01:29:40 +0200 Subject: [PATCH] Initial commit --- README.md | 3 ++ index.js | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 ++++ 3 files changed, 144 insertions(+) create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..56f77bf --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# @joepie91/result + +A rudimentary result type. Work in progress. diff --git a/index.js b/index.js new file mode 100644 index 0000000..9be77de --- /dev/null +++ b/index.js @@ -0,0 +1,133 @@ +"use strict"; + +function createResultObject(isSuccessful, containedValue) { + return { + __isResultType: true, + isOK: isSuccessful, + isError: !isSuccessful, + error: function () { + if (!isSuccessful) { + return containedValue; + } else { + // FIXME: Clearer error message, definitely a bug! + throw new Error(`The Result is in a success state`); + } + }, + value: function () { + if (isSuccessful) { + return containedValue; + } else { + throw containedValue; + } + }, + valueOr: function (defaultValue) { + if (isSuccessful) { + return containedValue; + } else { + return defaultValue; + } + }, + mapTo: function ({ ok, error }) { + let okMapper = ok ?? ((value) => Result.ok(value)); + let errorMapper = error ?? ((error) => Result.error(error)); + + if (this.isOK) { + let mapped = okMapper(containedValue); + + return (Result.isResult(mapped)) + ? mapped + : Result.ok(mapped); + } else { + let mapped = errorMapper(containedValue); + + return (Result.isResult(mapped)) + ? mapped + : Result.error(mapped); + } + }, + // valueOr: function (errorCode, errorMessage) { + // if (isSuccessful) { + // return containedValue; + // } else { + // // FIXME: Integrate with error-chain somehow? + // let error = new Error(errorMessage); + // error.code = errorCode; + // throw error; + // } + // }, + // FIXME: Chaining, Promise chain integration? + // FIXME: Serialization + // FIXME: Chaining with error filtering + }; +} + +let Result = module.exports = { + isResult: function (value) { + return (value != null && value.__isResultType === true); + }, + ok: function (value) { + // Emulate what Promises do on `resolve(...)` + if (this.isResult(value)) { + return value; + } else { + return createResultObject(true, value); + } + }, + error: function (error) { + return createResultObject(false, error); + }, + wrap: function (callback) { + // Always returns a Result + try { + let result = callback(); + return this.ok(result); + } catch (error) { + return this.error(error); + } + }, + wrapAsync: function (callback) { + // Always returns a Promise that resolves to a Result + return new Promise((resolve, _reject) => { + resolve(callback()); + }).then((result) => { + return this.ok(result); + }).catch((error) => { + return this.error(error); + }); + }, + // The below methods are used when it's unknown whether something will produce a Result or just return/throw + unwrapValue: function (value) { + if (Result.isResult(value)) { + return value.unwrap(); + } else { + return value; + } + }, + unwrap: function (callback) { + return Result.unwrapValue(callback()); + }, + unwrapAsync: function (callback) { + return new Promise((resolve, _reject) => { + resolve(callback()); + }).then((result) => { + return Result.unwrapValue(result); + }); + } +}; + + +/* IDEA: + +result.mapTo({ + ok: (value) => value * 2, + error: (error) => chain(error, ErrorType, "Foo Bar") +}) + +result.mapTo({ + // can return either a result or any value + ok: (value) => value * 2, + // can return either a result or an Error + error: (_error) => result.ok(0) +}) + +*/ diff --git a/package.json b/package.json new file mode 100644 index 0000000..9349d39 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "@joepie91/result", + "version": "0.1.0", + "main": "index.js", + "repository": "https://git.cryto.net/joepie91/result.git", + "author": "Sven Slootweg ", + "license": "WTFPL OR CC0-1.0" +}