// :: status? -> result? -> HTTPResult function HTTPResult(status,result) { this.status = 0; this.result = null; this._handlers = []; if ( status ) { this.set(status,result); } } HTTPResult.fromResponsePromise = function(promise,errorHandler) { var result = new HTTPResult(); promise.then(function(response){ result.set(response.statusCode,response.body); }, errorHandler && function(error){ var ret = errorHandler(error); if ( ret.constructor === HTTPResult ) { ret.handle(result.set.bind(result)); } else { result.set(500,ret); } }); return result; }; // isSet :: Bool HTTPResult.prototype.isSet = function() { return this.status !== 0; }; // set :: status -> result? -> () HTTPResult.prototype.set = function(status,result) { if ( this.isSet() ) { throw new Error("Result was already set."); } if ( typeof status !== 'number' ) { throw new Error("Status must be a number."); } this.status = status; this.result = result; for ( var i = 0; i < this._handlers.length; i++ ) { this._fire(this._handlers[i]); } }; // _fire :: (status -> result -> Either HTTPResult Any) -> () HTTPResult.prototype._fire = function(f) { var ret = f(this.status,this.result); if ( ret.constructor === HTTPResult ) { ret.handle(f._next.set.bind(f._next)); } else { f._next.set(this.status,ret); } }; /* handle :: Either (status -> result -> Either HTTPResult Any) * {number: (result -> Either HTTPResult Any), * 'default': (status -> result -> Either HTTPResult Any)} * -> HTTPResult */ HTTPResult.prototype.handle = function(fOrObj) { var f = typeof fOrObj === 'function' ? fOrObj : function(status,result) { if ( status in fOrObj ) { return fOrObj[status](result); } else if ( 'default' in fOrObj ) { return fOrObj['default'](status,result); } else { return result; } }; f._next = new HTTPResult(); if ( this.isSet() ) { this._fire(f); } else { this._handlers.push(f); } return f._next; }; module.exports = HTTPResult;