[487] | 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; |
---|