-
Notifications
You must be signed in to change notification settings - Fork 0
/
morphic.js
99 lines (85 loc) · 3.05 KB
/
morphic.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
var defaultMatcher = require("./matcher.js");
var defaultGenerateMatchers = require("./destructure.js").generateMatchers;
var defaultGenerateNamedFieldExtractors = require("./destructure.js").generateNamedFieldExtractors;
var defaultExtractNamedFields = require("./destructure.js").extractNamedFields;
var matchers = require("./matchers.js");
var util = require("util");
function putRecord(sink, namedFields, action) {
sink({
namedFields: namedFields,
action: action
});
}
function builder(sink) {
return {
"returnNamedMatch": function(name) {
sink(function(args) {
return args[name];
});
},
"returnArgument": function(n) {
sink(function() {
return arguments[n+1];
});
},
"throw": function(error) {
sink(function() {
throw error;
});
},
"return": function(value) {
sink(function() {
return value;
});
},
"then": sink
};
}
// This class is essentially syntactic sugar around the core matcher found in
// matcher.js
function morphic(options) {
var optionsIn = options || {};
var Matcher = optionsIn.matcherCore || defaultMatcher
var matcher = new Matcher(optionsIn);
var generateMatchers = optionsIn.generateMatchers || defaultGenerateMatchers;
var generateNamedFieldExtractors = optionsIn.generateNamedFieldExtractors || defaultGenerateNamedFieldExtractors;
var extractNamedFields = optionsIn.extractNamedFields || defaultExtractNamedFields;
putRecord(matcher.useFallback.bind(matcher), [], function() {
throw new Error("No methods matched input " + util.inspect(arguments));
});
var morphicFunction = function morphicFunction() {
var match = matcher.getRecordFromInput(arguments);
var extractedFields = extractNamedFields(match.namedFields || [], arguments);
var args = [extractedFields].concat(Array.from(arguments));
var action = match.action;
return action.apply(this, args);
};
morphicFunction.with = function() {
var generatedMatchers = generateMatchers(matchers, arguments);
var namedFields = generateNamedFieldExtractors(generatedMatchers);
return builder(
putRecord.bind(
undefined, matcher.addRecord.bind(matcher, generatedMatchers), namedFields));
};
morphicFunction.otherwise = function() {
return builder(
putRecord.bind(
undefined, matcher.useFallback.bind(matcher), []));
};
return morphicFunction;
}
morphic.null = matchers.matchLiteral.bind(undefined, null);
morphic.undefined = matchers.matchLiteral.bind(undefined, undefined);
var types = ["Object", "Boolean", "Number", "String"];
types.forEach(function(type) {
morphic[type] = matchers.matchType.bind(undefined, type);
});
var typeExact = ["string", "number", "boolean", "object", "symbol", "function"];
typeExact.forEach(function(type) {
morphic[type] = matchers.matchTypeExactly.bind(undefined, type);
});
morphic.either = matchers.matchEither;
morphic.literally = matchers.matchLiteral;
morphic.anything = matchers.matchAnything;
morphic.makeMatcher = matchers.makeUserFunction;
module.exports = morphic;