1 | // <init> :: status? -> result? -> HTTPResult |
---|
2 | function HTTPResult(status,result) { |
---|
3 | this.status = 0; |
---|
4 | this.result = null; |
---|
5 | this._handlers = []; |
---|
6 | if ( status ) { |
---|
7 | this.set(status,result); |
---|
8 | } |
---|
9 | } |
---|
10 | |
---|
11 | HTTPResult.fromResponsePromise = function(promise,errorHandler) { |
---|
12 | var result = new HTTPResult(); |
---|
13 | promise.then(function(response){ |
---|
14 | result.set(response.statusCode,response.body); |
---|
15 | }, errorHandler && function(error){ |
---|
16 | var ret = errorHandler(error); |
---|
17 | if ( ret.constructor === HTTPResult ) { |
---|
18 | ret.handle(result.set.bind(result)); |
---|
19 | } else { |
---|
20 | result.set(500,ret); |
---|
21 | } |
---|
22 | }); |
---|
23 | return result; |
---|
24 | }; |
---|
25 | |
---|
26 | // isSet :: Bool |
---|
27 | HTTPResult.prototype.isSet = function() { |
---|
28 | return this.status !== 0; |
---|
29 | }; |
---|
30 | |
---|
31 | // set :: status -> result? -> () |
---|
32 | HTTPResult.prototype.set = function(status,result) { |
---|
33 | if ( this.isSet() ) { throw new Error("Result was already set."); } |
---|
34 | if ( typeof status !== 'number' ) { throw new Error("Status must be a number."); } |
---|
35 | this.status = status; |
---|
36 | this.result = result; |
---|
37 | for ( var i = 0; i < this._handlers.length; i++ ) { |
---|
38 | this._fire(this._handlers[i]); |
---|
39 | } |
---|
40 | }; |
---|
41 | |
---|
42 | // _fire :: (status -> result -> Either HTTPResult Any) -> () |
---|
43 | HTTPResult.prototype._fire = function(f) { |
---|
44 | var ret = f(this.status,this.result); |
---|
45 | if ( ret.constructor === HTTPResult ) { |
---|
46 | ret.handle(f._next.set.bind(f._next)); |
---|
47 | } else { |
---|
48 | f._next.set(this.status,ret); |
---|
49 | } |
---|
50 | }; |
---|
51 | |
---|
52 | /* handle :: Either (status -> result -> Either HTTPResult Any) |
---|
53 | * {number: (result -> Either HTTPResult Any), |
---|
54 | * 'default': (status -> result -> Either HTTPResult Any)} |
---|
55 | * -> HTTPResult |
---|
56 | */ |
---|
57 | HTTPResult.prototype.handle = function(fOrObj) { |
---|
58 | var f = typeof fOrObj === 'function' ? |
---|
59 | fOrObj : |
---|
60 | function(status,result) { |
---|
61 | if ( status in fOrObj ) { |
---|
62 | return fOrObj[status](result); |
---|
63 | } else if ( 'default' in fOrObj ) { |
---|
64 | return fOrObj['default'](status,result); |
---|
65 | } else { |
---|
66 | return result; |
---|
67 | } |
---|
68 | }; |
---|
69 | f._next = new HTTPResult(); |
---|
70 | if ( this.isSet() ) { |
---|
71 | this._fire(f); |
---|
72 | } else { |
---|
73 | this._handlers.push(f); |
---|
74 | } |
---|
75 | return f._next; |
---|
76 | }; |
---|
77 | |
---|
78 | module.exports = HTTPResult; |
---|