search.scm 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. (library (search)
  2. (export make-general-comparator
  3. default-fallback-comparator
  4. default-string-comparator
  5. default-number-comparator
  6. default-vector-comparator
  7. default-boolean-comparator)
  8. (import (rnrs base)
  9. (only (guile)
  10. lambda* λ
  11. simple-format
  12. current-output-port
  13. string-contains
  14. pk)
  15. (alist-procs)
  16. (bool-utils)
  17. ;; SRFIs
  18. ;; SRFI 1 - list procs
  19. (srfi srfi-1)
  20. ;; SRFI 43 - vector procs
  21. (srfi srfi-43)
  22. ;; SRFI 69 - hash-table procs
  23. (srfi srfi-69)))
  24. (define default-string-comparator
  25. (λ (attr-val searched-val)
  26. "Either equal to the searched string or containing the
  27. searched string."
  28. (or (string=? attr-val searched-val)
  29. (not
  30. (equal? #f
  31. (string-contains attr-val searched-val))))))
  32. (define default-number-comparator
  33. (λ (attr-val searched-val)
  34. "Equal to the searched number."
  35. (cond
  36. [(string? searched-val)
  37. (let ([as-num (string->number searched-val)])
  38. (cond
  39. [(number? as-num) (= attr-val as-num)]
  40. [else #f]))]
  41. [(number? searched-val)
  42. (= attr-val searched-val)]
  43. [else
  44. #f])))
  45. (define default-boolean-comparator
  46. (λ (attr-val searched-val)
  47. "Equal to searched string converted to boolean."
  48. (equal? attr-val
  49. (string->boolean
  50. searched-val
  51. ;; If the searched value cannot be converted to
  52. ;; a boolean, simply use it as is, which will
  53. ;; result in the result being #f.
  54. #:conversion-error-thunk (λ () searched-val)))))
  55. (define default-vector-comparator
  56. (λ (attr-val searched-val)
  57. "Equal or containing a value, which is equal according
  58. to on of the other default comparators."
  59. (vector-fold (λ (index acc elem)
  60. (or acc
  61. (cond
  62. [(boolean? elem)
  63. (default-boolean-comparator elem searched-val)]
  64. [(number? elem)
  65. (default-number-comparator elem searched-val)]
  66. [(string? elem)
  67. (default-string-comparator elem searched-val)]
  68. [else
  69. (equal? elem searched-val)])))
  70. #f
  71. attr-val)))
  72. (define default-fallback-comparator
  73. (λ (attr-val searched-val)
  74. "Equal."
  75. (equal? attr-val searched-val)))
  76. (define make-general-comparator
  77. (lambda* (#:key
  78. (number-comparator #f)
  79. (string-comparator #f)
  80. (boolean-comparator #f)
  81. (vector-comparator #f)
  82. (fallback-comparator #f))
  83. "Create a general search function using the given
  84. comparators. If one of the comparators is #f the
  85. FALLBACK-COMPARATOR will be used in its stead."
  86. (λ (attr-val seeked)
  87. ;; This code looks kind of dumb. Tried a hash-table of
  88. ;; type predicates and corresponding comparators, but
  89. ;; that did not look much better. Not sure how to
  90. ;; improve it.
  91. (cond
  92. [(string? attr-val)
  93. ((or string-comparator default-string-comparator) attr-val seeked)]
  94. [(number? attr-val)
  95. ((or number-comparator default-number-comparator) attr-val seeked)]
  96. [(boolean? attr-val)
  97. ((or boolean-comparator default-boolean-comparator) attr-val seeked)]
  98. [(vector? attr-val)
  99. ((or vector-comparator default-vector-comparator) attr-val seeked)]
  100. [else
  101. (fallback-comparator attr-val seeked)]))))