Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
minecrawler committed Sep 19, 2017
2 parents 78d813e + 9c1ea78 commit ca84128
Show file tree
Hide file tree
Showing 29 changed files with 397 additions and 245 deletions.
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';


require('./src/result._init.c');
require('./src/result.and.c');
require('./src/result.andThen.c');
require('./src/result.expect.c');
Expand All @@ -20,7 +19,11 @@ require('./src/result.or.c');
require('./src/result.orElse.c');
require('./src/result.registerGlobals.c');
require('./src/result.unwrap.c');
require('./src/result.unwrapAnd.c');
require('./src/result.unwrapAndThen.c');
require('./src/result.unwrapErr.c');
require('./src/result.unwrapOr.c');
require('./src/result.unwrapOrElse.c');


module.exports = require('./interface/result.h');
6 changes: 6 additions & 0 deletions interface/result-sym.h.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
isOk: Symbol(),
value: Symbol(),
};
72 changes: 49 additions & 23 deletions interface/result.h.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
* @returns {*}
*/

/**
* This Callback is used to produce a final Value
*
* @callback ValueEmitter
* @param {*} val
* `val` will contain the result of {Result}.
* @returns {*}
*/

/**
* This Callback is used as a return-handler
*
Expand All @@ -60,17 +69,6 @@
* @type {Result}
*/
module.exports = class Result {

/**
* Create new Result from either a value or an error
* Leave the one you don't need undefined
* You have to pass something to exactly one of the two
*
* @param {*} val
* @param {*} err
*/
constructor (val, err) { this._init(val, err); };

/**
* Create success Result with a return value.
*
Expand Down Expand Up @@ -141,40 +139,36 @@ module.exports = class Result {
iter() { throw new Error ('Not Implemented: Result.iter'); };

/**
* Returns `val` if the result is Ok, otherwise returns the Err value of itself.
* Returns `Ok(val)` if the result is Ok, otherwise returns `Err(err)` of itself.
*
* @param {*} val
* @returns {*}
* @returns {Result}
*/
and(val) { throw new Error ('Not Implemented: Result.and'); };

/**
* Calls `resultEmitter` if the result is Ok, otherwise returns the Err value of itself.
* Calls `resultEmitter` if the result is Ok, otherwise returns `Err(err)` value of itself.
* This function can be used for control flow based on Result values.
*
* @param {ResultEmitter} resultEmitter
* @returns {*}
* @returns {Result}
*/
andThen(resultEmitter) { throw new Error ('Not Implemented: Result.andThen'); };

/**
* Returns `val` if the result is Err, otherwise returns the Ok value of itself.
* Since there are no strict types in JS, this method and unwrapOr are identical.
* Returns `Ok(val)` if the result is Err, otherwise returns `Ok(ok)` of itself.
*
* @alias unwrapOr
* @param {*} val
* @returns {*}
* @returns {Result}
*/
or(val) { throw new Error ('Not Implemented: Result.or'); };

/**
* Calls `resultEmitter` if the result is Err, otherwise returns the Ok value of itself.
* Calls `resultEmitter` if the result is Err, otherwise returns the `Ok(ok)` value of itself.
* This function can be used for control flow based on result values.
* Since there are no strict types in JS, this method and unwrapOrElse are identical.
*
* @alias unwrapOrElse
* @param {ResultEmitter} resultEmitter
* @returns {*}
* @returns {Result}
*/
orElse(resultEmitter) { throw new Error ('Not Implemented: Result.orElse'); };

Expand All @@ -186,6 +180,22 @@ module.exports = class Result {
*/
unwrap() { throw new Error ('Not Implemented: Result.unwrap'); };

/**
* Unwraps a result, yielding the content of optb. Else it throws.
*
* @param {*} optb
* @return {*}
*/
unwrapAnd(optb) { throw new Error ('Not Implemented: Result.unwrapAnd'); };

/**
* Unwraps a result, calling valEmitter with its value. If the value is an Err then it throws.
*
* @param {ValueEmitter} valEmitter
* @return {*}
*/
unwrapAndThen(valEmitter) { throw new Error ('Not Implemented: Result.unwrapAndThen'); };

/**
* Unwraps a result, yielding the content of an Err.
*
Expand All @@ -194,6 +204,22 @@ module.exports = class Result {
*/
unwrapErr() { throw new Error ('Not Implemented: Result.unwrapErr'); };

/**
* Unwraps a result, yielding the content of an Ok. Else it returns optb.
*
* @param {*} optb
* @return {*}
*/
unwrapOr(optb) { throw new Error ('Not Implemented: Result.unwrapOr'); };

/**
* Unwraps a result, yielding the content of an Ok. If the value is an Err then it calls valEmitter with its value.
*
* @param {ValueEmitter} valEmitter
* @return {*}
*/
unwrapOrElse(valEmitter) { throw new Error ('Not Implemented: Result.unwrapOrElse'); };

/**
* Unwraps a result, yielding the content of an Ok.
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "result-js",
"version": "3.0.2",
"version": "4.0.0",
"description": "Rusty Monad Results for JS",
"author": {
"email": "me@marco-alka.de",
Expand Down
36 changes: 0 additions & 36 deletions src/result._init.c.js

This file was deleted.

11 changes: 9 additions & 2 deletions src/result.and.c.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
'use strict';

require('../interface/result.h').prototype.and = function ($val) {
const H = require('../interface/result.h').prototype;
const sym = require('../interface/result-sym.h');

return this.isOk() ? $val : this._err;

H.and = function ($val) {
if (this[sym.isOk]) {
this[sym.value] = $val;
}

return this;
};
11 changes: 9 additions & 2 deletions src/result.andThen.c.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
'use strict';

require('../interface/result.h').prototype.andThen = function ($resultEmitter) {
const H = require('../interface/result.h').prototype;
const sym = require('../interface/result-sym.h');

return this.isOk() ? $resultEmitter(this._val) : this._err;

H.andThen = function ($resultEmitter) {
if (this[sym.isOk]) {
this[sym.value] = $resultEmitter(this[sym.value]);
}

return this;
};
11 changes: 7 additions & 4 deletions src/result.expect.c.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
'use strict';

require('../interface/result.h').prototype.expect = function ($msg) {
const sym = require('../interface/result-sym.h');

return this.orElse(() => {

require('../interface/result.h').prototype.expect = function ($msg) {
if (!this[sym.isOk]) {
const msg = typeof $msg === 'string' ? $msg : 'ERROR: $msg is not a string. Also -> ';
throw new Error(`${msg}: ${this._err.toString()}`);
});
throw new Error(`${msg}: ${this[sym.value].toString()}`);
}

return this[sym.value];
};
9 changes: 5 additions & 4 deletions src/result.expectErr.c.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict';

require('../interface/result.h').prototype.expectErr = function ($msg) {
const sym = require('../interface/result-sym.h');

if (this.isErr()) {

return this._err;
require('../interface/result.h').prototype.expectErr = function ($msg) {
if (!this[sym.isOk]) {
return this[sym.value];
}

const msg = typeof $msg === 'string' ? $msg : 'ERROR: $msg is not a string. Also -> ';
throw new Error(`${msg}: ${this._ok.toString()}`);
throw new Error(`${msg}: ${this[sym.value].toString()}`);
};
11 changes: 8 additions & 3 deletions src/result.fromError.c.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
'use strict';

const h = require('../interface/result.h');
const H = require('../interface/result.h');
const sym = require('../interface/result-sym.h');


h.fromError = function ($err) {
H.fromError = function ($err) {
const result = new H();

return new h(undefined, $err);
result[sym.isOk] = false;
result[sym.value] = $err;

return result;
};
11 changes: 8 additions & 3 deletions src/result.fromSuccess.c.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
'use strict';

const h = require('../interface/result.h');
const H = require('../interface/result.h');
const sym = require('../interface/result-sym.h');


h.fromSuccess = function ($val) {
H.fromSuccess = function ($val) {
const result = new H();

return new h($val);
result[sym.isOk] = true;
result[sym.value] = $val;

return result;
};
16 changes: 10 additions & 6 deletions src/result.fromTry.c.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
'use strict';

const h = require('../interface/result.h');
const H = require('../interface/result.h');
const sym = require('../interface/result-sym.h');


h.fromTry = function ($fun) {
H.fromTry = function ($fun) {
const result = new H();

try {

return h.fromSuccess($fun());
result[sym.value] = $fun();
result[sym.isOk] = true;
}
catch ($err) {

return h.fromError($err);
result[sym.value] = $err;
result[sym.isOk] = false;
}

return result;
};
6 changes: 4 additions & 2 deletions src/result.isErr.c.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

require('../interface/result.h').prototype.isErr = function () {
const sym = require('../interface/result-sym.h');


return this._err !== null;
require('../interface/result.h').prototype.isErr = function () {
return !this[sym.isOk];
};
6 changes: 4 additions & 2 deletions src/result.isOk.c.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

require('../interface/result.h').prototype.isOk = function () {
const sym = require('../interface/result-sym.h');


return this._err === null;
require('../interface/result.h').prototype.isOk = function () {
return !!this[sym.isOk];
};
10 changes: 4 additions & 6 deletions src/result.iter.c.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
'use strict';

const hProto = require('../interface/result.h').prototype;
const sym = require('../interface/result-sym.h');


hProto.iter = function () {

const self = this;
return {

return {
[Symbol.iterator]: function* () {

if (self.isOk()) {

yield self._val;
if (self[sym.isOk]) {
yield self[sym.value];
}
},
};
Expand Down
Loading

0 comments on commit ca84128

Please sign in to comment.