-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathprotocol.js
More file actions
59 lines (47 loc) · 1.58 KB
/
protocol.js
File metadata and controls
59 lines (47 loc) · 1.58 KB
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
import Core from '../core';
//https://github.com/airportyh/protomorphism
class Protocol{
constructor(spec){
this.registry = new Map();
this.fallback = null;
for (let funName in spec){
this[funName] = createFun(funName).bind(this);
}
function createFun(funName){
return function(...args) {
let thing = args[0];
let fun = null;
if(Number.isInteger(thing) && this.hasImplementation(Core.Integer)){
fun = this.registry.get(Core.Integer)[funName];
}else if(typeof thing === "number" && !Number.isInteger(thing) && this.hasImplementation(Core.Float)){
fun = this.registry.get(Core.Float)[funName];
}else if(typeof thing === "string" && this.hasImplementation(Core.BitString)){
fun = this.registry.get(Core.BitString)[funName];
}else if(this.hasImplementation(thing)){
fun = this.registry.get(thing.constructor)[funName];
}else if(this.fallback){
fun = this.fallback[funName];
}
if(fun != null){
let retval = fun.apply(this, args);
return retval;
}
throw new Error("No implementation found for " + thing);
};
}
}
implementation(type, implementation){
if(type === null){
this.fallback = implementation;
}else{
this.registry.set(type, implementation);
}
}
hasImplementation(thing) {
if (thing === Core.Integer || thing === Core.Float || Core.BitString){
return this.registry.has(thing);
}
return this.registry.has(thing.constructor);
}
}
export default Protocol;