buildMatchFn.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. export function buildMatchFn(args) {
  2. return (string, options = {}) => {
  3. const width = options.width;
  4. const matchPattern =
  5. (width && args.matchPatterns[width]) ||
  6. args.matchPatterns[args.defaultMatchWidth];
  7. const matchResult = string.match(matchPattern);
  8. if (!matchResult) {
  9. return null;
  10. }
  11. const matchedString = matchResult[0];
  12. const parsePatterns =
  13. (width && args.parsePatterns[width]) ||
  14. args.parsePatterns[args.defaultParseWidth];
  15. const key = Array.isArray(parsePatterns)
  16. ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString))
  17. : // [TODO] -- I challenge you to fix the type
  18. findKey(parsePatterns, (pattern) => pattern.test(matchedString));
  19. let value;
  20. value = args.valueCallback ? args.valueCallback(key) : key;
  21. value = options.valueCallback
  22. ? // [TODO] -- I challenge you to fix the type
  23. options.valueCallback(value)
  24. : value;
  25. const rest = string.slice(matchedString.length);
  26. return { value, rest };
  27. };
  28. }
  29. function findKey(object, predicate) {
  30. for (const key in object) {
  31. if (
  32. Object.prototype.hasOwnProperty.call(object, key) &&
  33. predicate(object[key])
  34. ) {
  35. return key;
  36. }
  37. }
  38. return undefined;
  39. }
  40. function findIndex(array, predicate) {
  41. for (let key = 0; key < array.length; key++) {
  42. if (predicate(array[key])) {
  43. return key;
  44. }
  45. }
  46. return undefined;
  47. }