Initial commit
commit
ab53f080b2
@ -0,0 +1,3 @@
|
||||
# @joepie91/result
|
||||
|
||||
A rudimentary result type. Work in progress.
|
@ -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)
|
||||
})
|
||||
|
||||
*/
|
@ -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 <admin@cryto.net>",
|
||||
"license": "WTFPL OR CC0-1.0"
|
||||
}
|
Loading…
Reference in New Issue