Skip to content

Commit

Permalink
Release 0.8
Browse files Browse the repository at this point in the history
featuring the new type-validating match
  • Loading branch information
uniphil committed Oct 21, 2015
1 parent b7f0b86 commit b07af8d
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 75 deletions.
207 changes: 136 additions & 71 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,81 @@
* @author uniphil
*/

'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }

var _ = Symbol('Union match catch-all symbol');

/**
* @throws Error if the match is not exhaustive, or if there are weird keys
* @throws Error when the match is not exhaustive
* @throws Error when there are weird keys
* @throws Error when `option` is the wrong type for this match
* @param {EnumOption} option The instance to match against
* @param {Object} paths The optionName: callback mapping
* @returns {any} The result of calling the matching callback
*/
'use strict';
function _match(option, paths) {
if (!(option instanceof this.OptionClass)) {
throw new Error('Union match: called on a non-member option: \'' + option + '\'');
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
for (var _iterator = Object.keys(paths)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var k = _step.value;

function _match(to) {
for (var k in to) {
if (to.hasOwnProperty(k)) {
if (!this.options.hasOwnProperty(k) && k !== '_') {
if (!option.options.hasOwnProperty(k) && k !== _) {
throw new Error('Union match: unrecognized match option: \'' + k + '\'');
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (typeof to._ === 'function') {

if (typeof paths[_] === 'function') {
// match is de-facto exhaustive w/ `_`
if (typeof to[this.name] === 'function') {
return to[this.name].apply(null, this.data);
if (typeof paths[option.name] === 'function') {
return paths[option.name].apply(paths, _toConsumableArray(option.data));
} else {
return to._(this);
return paths[_](option);
}
} else {
// ensure match is exhaustive
for (var k in this.options) {
if (typeof to[k] !== 'function') {
for (var k in option.options) {
if (typeof paths[k] !== 'function') {
throw new Error('Union match: Non-exhaustive match is missing \'' + k + '\'');
}
}
return to[this.name].apply(null, this.data);
return paths[option.name].apply(paths, _toConsumableArray(option.data));
}
};
}

function unionOptionToString() {
return '[UnionOption ' + this.name + '(' + this.data.join(', ') + ') ' + ('from Union { ' + Object.keys(this.options).join(', ') + ' }]');
}

function _factory(options, name, UnionOptionClass) {
return function () {
var data = [];
for (var i = 0; i < arguments.length; i++) {
data[i] = arguments[i];
for (var _len = arguments.length, data = Array(_len), _key = 0; _key < _len; _key++) {
data[_key] = arguments[_key];
}

return new UnionOptionClass(options, name, data);
};
}
Expand All @@ -51,40 +89,83 @@ function Union(options) {
var static_ = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var factory = arguments.length <= 3 || arguments[3] === undefined ? _factory : arguments[3];

if (options.hasOwnProperty('toString')) {
throw new Error('Union: cannot use reserved name `toString` as part of a Union');
}
if (options.hasOwnProperty('match')) {
throw new Error('Union: cannot use reserved name `match` as part of a Union');
}
if (options.hasOwnProperty('OptionClass')) {
throw new Error('Union: cannot use reserved name `UnionClass` as part of a Union');
}
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;

try {
for (var _iterator2 = Object.keys(static_)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var k = _step2.value;

if (options.hasOwnProperty(k)) {
throw new Error('Union: cannot add static method \'' + k + '\' to Union which ' + ('has the same name as a member (members: ' + options.join(', ') + ').'));
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
_iterator2['return']();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}

function UnionOption(options, name, data) {
this.options = options;
this.name = name;
this.data = data;
}
UnionOption.prototype = proto;
if (typeof proto.match === 'undefined') {
proto.match = _match;
}
if (!proto.hasOwnProperty('toString')) {
proto.toString = function () {
return '[UnionOption ' + this.name + '(' + this.data.join(', ') + ') ' + ('from Union { ' + Object.keys(this.options).join(', ') + ' }]');
};
}
var union_ = Object.keys(options).reduce(function (obj, name) {
obj[name] = factory(options, name, UnionOption);
return obj;
}, {});
if (options.hasOwnProperty('toString')) {
throw new Error('Union: cannot use reserved name `toString` as part of a Union');
}
union_.toString = function () {
return '[Union { ' + Object.keys(options).join(', ') + ' }]';
};
for (var k in static_) {
if (static_.hasOwnProperty(k)) {
union_[k] = static_[k];
UnionOption.prototype = _extends({
toString: unionOptionToString
}, proto);
var union = _extends({
OptionClass: UnionOption,
toString: function toString() {
return '[Union { ' + Object.keys(options).join(', ') + ' }]';
},
match: _match
}, static_);
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;

try {
for (var _iterator3 = Object.keys(options)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var _name = _step3.value;

union[_name] = factory(options, _name, UnionOption);
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3['return']) {
_iterator3['return']();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
if (union_.hasOwnProperty('OptionClass')) {
throw new Error('Union: cannot use reserved name `UnionClass` as part of a Union');
}
union_.OptionClass = UnionOption;
return union_;

return union;
}

var maybeProto = {
Expand All @@ -95,16 +176,6 @@ var maybeProto = {
return Maybe.Some(value);
}
},
/**
* @throws Error if the match is not exhaustive
*/
match: function match(paths) {
return _match.call({
options: this.options,
name: this.name,
data: [this.data]
}, paths);
},
isSome: function isSome() {
return this.name === 'Some';
},
Expand Down Expand Up @@ -164,6 +235,10 @@ var maybeProto = {
};

var maybeStatic = {
match: function match(option, paths) {
var normalOption = new this.OptionClass(option.options, option.name, [option.data]);
return _match.call(this, normalOption, paths);
},
all: function all(values) {
return values.reduce(function (res, next) {
return res.andThen(function (resArr) {
Expand Down Expand Up @@ -196,11 +271,6 @@ var Maybe = Union({
}
});

var ResultError = Union({
UnwrapErrAsOk: null,
UnwrapErr: null
});

var resultProto = {
_promote: function _promote(value) {
if (value instanceof Result.OptionClass) {
Expand All @@ -209,16 +279,6 @@ var resultProto = {
return Result.Ok(value);
}
},
/**
* @throws Error if the match is not exhaustive
*/
match: function match(paths) {
return _match.call({
options: this.options,
name: this.name,
data: [this.data]
}, paths);
},
isOk: function isOk() {
return this.name === 'Ok';
},
Expand Down Expand Up @@ -262,22 +322,26 @@ var resultProto = {
if (this.name === 'Ok') {
return this.data;
} else {
throw ResultError.UnwrapErr(this.data);
throw new Error('Result Union: Tried to .unwrap() Err as Ok');
}
},
/**
* @throws the value from Ok(value)
*/
unwrapErr: function unwrapErr() {
if (this.name === 'Ok') {
throw ResultError.UnwrapErrAsOk(this.data);
throw new Error('Result Union: Tried to .unwrap() Ok as Err');
} else {
return this.data;
}
}
};

var resultStatic = {
match: function match(option, paths) {
var normalOption = new this.OptionClass(option.options, option.name, [option.data]);
return _match.call(this, normalOption, paths);
},
all: function all(values) {
return values.reduce(function (res, next) {
return res.andThen(function (resArr) {
Expand Down Expand Up @@ -313,6 +377,7 @@ var Result = Union({

module.exports = {
Union: Union,
_: _,

Maybe: Maybe,
Some: Maybe.Some,
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": "results",
"version": "0.7.0",
"version": "0.8.0",
"description": "Rust-inspired Result and Option tools for javascript",
"main": "index.js",
"scripts": {
Expand Down
4 changes: 1 addition & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ Changes
### v0.8.0
_in progress_
2015-10-21
#### Breaking
Expand All @@ -630,8 +630,6 @@ _in progress_
});
```
#### Other Changes
### v0.7.0
Expand Down

0 comments on commit b07af8d

Please sign in to comment.