results.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. var _ = require("underscore");
  2. exports.Result = Result;
  3. exports.success = success;
  4. exports.warning = warning;
  5. exports.error = error;
  6. function Result(value, messages) {
  7. this.value = value;
  8. this.messages = messages || [];
  9. }
  10. Result.prototype.map = function(func) {
  11. return new Result(func(this.value), this.messages);
  12. };
  13. Result.prototype.flatMap = function(func) {
  14. var funcResult = func(this.value);
  15. return new Result(funcResult.value, combineMessages([this, funcResult]));
  16. };
  17. Result.prototype.flatMapThen = function(func) {
  18. var that = this;
  19. return func(this.value).then(function(otherResult) {
  20. return new Result(otherResult.value, combineMessages([that, otherResult]));
  21. });
  22. };
  23. Result.combine = function(results) {
  24. var values = _.flatten(_.pluck(results, "value"));
  25. var messages = combineMessages(results);
  26. return new Result(values, messages);
  27. };
  28. function success(value) {
  29. return new Result(value, []);
  30. }
  31. function warning(message) {
  32. return {
  33. type: "warning",
  34. message: message
  35. };
  36. }
  37. function error(exception) {
  38. return {
  39. type: "error",
  40. message: exception.message,
  41. error: exception
  42. };
  43. }
  44. function combineMessages(results) {
  45. var messages = [];
  46. _.flatten(_.pluck(results, "messages"), true).forEach(function(message) {
  47. if (!containsMessage(messages, message)) {
  48. messages.push(message);
  49. }
  50. });
  51. return messages;
  52. }
  53. function containsMessage(messages, message) {
  54. return _.find(messages, isSameMessage.bind(null, message)) !== undefined;
  55. }
  56. function isSameMessage(first, second) {
  57. return first.type === second.type && first.message === second.message;
  58. }