_dispatchable.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import _isArray from "./_isArray.js";
  2. import _isTransformer from "./_isTransformer.js";
  3. /**
  4. * Returns a function that dispatches with different strategies based on the
  5. * object in list position (last argument). If it is an array, executes [fn].
  6. * Otherwise, if it has a function with one of the given method names, it will
  7. * execute that function (functor case). Otherwise, if it is a transformer,
  8. * uses transducer created by [transducerCreator] to return a new transformer
  9. * (transducer case).
  10. * Otherwise, it will default to executing [fn].
  11. *
  12. * @private
  13. * @param {Array} methodNames properties to check for a custom implementation
  14. * @param {Function} transducerCreator transducer factory if object is transformer
  15. * @param {Function} fn default ramda implementation
  16. * @return {Function} A function that dispatches on object in list position
  17. */
  18. export default function _dispatchable(methodNames, transducerCreator, fn) {
  19. return function () {
  20. if (arguments.length === 0) {
  21. return fn();
  22. }
  23. var obj = arguments[arguments.length - 1];
  24. if (!_isArray(obj)) {
  25. var idx = 0;
  26. while (idx < methodNames.length) {
  27. if (typeof obj[methodNames[idx]] === 'function') {
  28. return obj[methodNames[idx]].apply(obj, Array.prototype.slice.call(arguments, 0, -1));
  29. }
  30. idx += 1;
  31. }
  32. if (_isTransformer(obj)) {
  33. var transducer = transducerCreator.apply(null, Array.prototype.slice.call(arguments, 0, -1));
  34. return transducer(obj);
  35. }
  36. }
  37. return fn.apply(this, arguments);
  38. };
  39. }