csv_decision 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +112 -93
  4. data/benchmarks/rufus_decision.rb +9 -1
  5. data/csv_decision.gemspec +6 -6
  6. data/doc/CSVDecision.html +54 -90
  7. data/doc/CSVDecision/CellValidationError.html +1 -1
  8. data/doc/CSVDecision/Columns.html +104 -45
  9. data/doc/CSVDecision/Columns/Dictionary.html +40 -24
  10. data/doc/CSVDecision/Columns/Entry.html +209 -22
  11. data/doc/CSVDecision/Constant.html +9 -50
  12. data/doc/CSVDecision/Data.html +182 -47
  13. data/doc/CSVDecision/Decide.html +97 -93
  14. data/doc/CSVDecision/Decision.html +105 -294
  15. data/doc/CSVDecision/Error.html +1 -1
  16. data/doc/CSVDecision/FileError.html +1 -1
  17. data/doc/CSVDecision/Function.html +18 -7
  18. data/doc/CSVDecision/Guard.html +245 -0
  19. data/doc/CSVDecision/Header.html +58 -50
  20. data/doc/CSVDecision/Input.html +20 -12
  21. data/doc/CSVDecision/Load.html +80 -14
  22. data/doc/CSVDecision/Matchers.html +237 -279
  23. data/doc/CSVDecision/Matchers/Constant.html +280 -13
  24. data/doc/CSVDecision/Matchers/Function.html +188 -19
  25. data/doc/CSVDecision/Matchers/Guard.html +568 -0
  26. data/doc/CSVDecision/Matchers/Matcher.html +200 -14
  27. data/doc/CSVDecision/Matchers/Numeric.html +165 -13
  28. data/doc/CSVDecision/Matchers/Pattern.html +56 -163
  29. data/doc/CSVDecision/Matchers/Range.html +48 -37
  30. data/doc/CSVDecision/Matchers/Symbol.html +161 -16
  31. data/doc/CSVDecision/Numeric.html +4 -4
  32. data/doc/CSVDecision/Options.html +53 -55
  33. data/doc/CSVDecision/Parse.html +23 -13
  34. data/doc/CSVDecision/ScanRow.html +461 -73
  35. data/doc/CSVDecision/Symbol.html +4 -4
  36. data/doc/CSVDecision/Table.html +185 -79
  37. data/doc/_index.html +15 -28
  38. data/doc/class_list.html +1 -1
  39. data/doc/file.README.html +105 -82
  40. data/doc/index.html +105 -82
  41. data/doc/method_list.html +137 -113
  42. data/doc/top-level-namespace.html +1 -1
  43. data/lib/csv_decision.rb +2 -5
  44. data/lib/csv_decision/columns.rb +14 -5
  45. data/lib/csv_decision/data.rb +24 -6
  46. data/lib/csv_decision/decide.rb +18 -20
  47. data/lib/csv_decision/decision.rb +106 -42
  48. data/lib/csv_decision/header.rb +44 -23
  49. data/lib/csv_decision/input.rb +4 -2
  50. data/lib/csv_decision/load.rb +7 -3
  51. data/lib/csv_decision/matchers.rb +49 -41
  52. data/lib/csv_decision/matchers/constant.rb +62 -4
  53. data/lib/csv_decision/matchers/function.rb +33 -2
  54. data/lib/csv_decision/matchers/guard.rb +143 -0
  55. data/lib/csv_decision/matchers/numeric.rb +34 -3
  56. data/lib/csv_decision/matchers/pattern.rb +11 -4
  57. data/lib/csv_decision/matchers/range.rb +34 -26
  58. data/lib/csv_decision/matchers/symbol.rb +71 -5
  59. data/lib/csv_decision/options.rb +31 -20
  60. data/lib/csv_decision/parse.rb +28 -9
  61. data/lib/csv_decision/scan_row.rb +79 -13
  62. data/lib/csv_decision/table.rb +34 -23
  63. data/spec/csv_decision/columns_spec.rb +32 -7
  64. data/spec/csv_decision/constant_spec.rb +2 -26
  65. data/spec/csv_decision/decision_spec.rb +0 -9
  66. data/spec/csv_decision/examples_spec.rb +33 -16
  67. data/spec/csv_decision/matchers/function_spec.rb +1 -1
  68. data/spec/csv_decision/matchers/guard_spec.rb +153 -0
  69. data/spec/csv_decision/matchers/numeric_spec.rb +1 -1
  70. data/spec/csv_decision/matchers/pattern_spec.rb +2 -2
  71. data/spec/csv_decision/matchers/range_spec.rb +2 -2
  72. data/spec/csv_decision/matchers/symbol_spec.rb +1 -1
  73. data/spec/csv_decision/options_spec.rb +3 -3
  74. data/spec/csv_decision/table_spec.rb +96 -12
  75. data/spec/data/valid/benchmark_regexp.csv +10 -0
  76. data/spec/data/valid/regular_expressions.csv +11 -0
  77. metadata +14 -9
  78. data/lib/csv_decision/constant.rb +0 -54
  79. data/lib/csv_decision/function.rb +0 -32
  80. data/lib/csv_decision/numeric.rb +0 -38
  81. data/lib/csv_decision/symbol.rb +0 -73
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # CSV Decision: CSV based Ruby decision tables.
4
- # Created December 2017 by Brett Vickers
5
- # See LICENSE and README.md for details.
6
- module CSVDecision
7
- # Recognise Ruby-like numeric comparison expressions.
8
- module Numeric
9
- # For example: >= 100 or != 0
10
- COMPARISON = /\A(?<comparator><=|>=|<|>|!=)\s*(?<value>\S.*)\z/
11
- private_constant :COMPARISON
12
-
13
- # Coerce the input value to a numeric representation before invoking the comparison.
14
- # If the coercion fails, it will produce a nil value which always fails to match.
15
- COMPARATORS = {
16
- '>' => proc { |numeric_cell, value| Matchers.numeric(value)&.> numeric_cell },
17
- '>=' => proc { |numeric_cell, value| Matchers.numeric(value)&.>= numeric_cell },
18
- '<' => proc { |numeric_cell, value| Matchers.numeric(value)&.< numeric_cell },
19
- '<=' => proc { |numeric_cell, value| Matchers.numeric(value)&.<= numeric_cell },
20
- '!=' => proc { |numeric_cell, value| Matchers.numeric(value)&.!= numeric_cell }
21
- }.freeze
22
- private_constant :COMPARATORS
23
-
24
- # @param (see Matchers::Matcher#matches?)
25
- # @return (see Matchers::Matcher#matches?)
26
- def self.matches?(cell)
27
- match = COMPARISON.match(cell)
28
- return false unless match
29
-
30
- numeric_cell = Matchers.to_numeric(match['value'])
31
- return false unless numeric_cell
32
-
33
- comparator = match['comparator']
34
- Proc.with(type: :proc,
35
- function: COMPARATORS[comparator].curry[numeric_cell].freeze)
36
- end
37
- end
38
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # CSV Decision: CSV based Ruby decision tables.
4
- # Created December 2017 by Brett Vickers
5
- # See LICENSE and README.md for details.
6
- module CSVDecision
7
- # Recognise column symbol comparison expressions in input column data cells - e.g., +> :column+ or +!= :column+.
8
- module Symbol
9
- # Symbol comparison - e.g., > :column or != :column
10
- SYMBOL_COMPARE =
11
- "(?<comparator>#{Matchers::EQUALS}|!=|<|>|>=|<=)?\\s*:(?<name>#{Header::COLUMN_NAME})"
12
- private_constant :SYMBOL_COMPARE
13
-
14
- # Symbol comparision regular expression.
15
- SYMBOL_COMPARE_RE = Matchers.regexp(SYMBOL_COMPARE)
16
- private_constant :SYMBOL_COMPARE_RE
17
-
18
- # These procs compare one input hash value to another, and so do not coerce numeric values.
19
- # Note that we do *not* check +hash.key?(symbol)+, so a +nil+ value will match a missing hash key.
20
- EQUALITY = {
21
- ':=' => proc { |symbol, value, hash| value == hash[symbol] },
22
- '!=' => proc { |symbol, value, hash| value != hash[symbol] }
23
- }.freeze
24
- private_constant :EQUALITY
25
-
26
- def self.compare_proc(compare)
27
- proc { |symbol, value, hash| compare?(lhs: value, compare: compare, rhs: hash[symbol]) }
28
- end
29
- private_class_method :compare_proc
30
-
31
- COMPARE = {
32
- # Equality and inequality - create a lambda proc by calling with the actual column name symbol
33
- ':=' => ->(symbol) { EQUALITY[':='].curry[symbol].freeze },
34
- '=' => ->(symbol) { EQUALITY[':='].curry[symbol].freeze },
35
- '==' => ->(symbol) { EQUALITY[':='].curry[symbol].freeze },
36
- '!=' => ->(symbol) { EQUALITY['!='].curry[symbol].freeze },
37
-
38
- # Comparisons - create a lambda proc by calling with the actual column name symbol.
39
- '>' => ->(symbol) { compare_proc(:'>' ).curry[symbol].freeze },
40
- '>=' => ->(symbol) { compare_proc(:'>=').curry[symbol].freeze },
41
- '<' => ->(symbol) { compare_proc(:'<' ).curry[symbol].freeze },
42
- '<=' => ->(symbol) { compare_proc(:'<=').curry[symbol].freeze },
43
- }.freeze
44
- private_constant :COMPARE
45
-
46
- def self.compare?(lhs:, compare:, rhs:)
47
- # Is the rhs a superclass of lhs, and does rhs respond to the compare method?
48
- return lhs.public_send(compare, rhs) if lhs.is_a?(rhs.class) && rhs.respond_to?(compare)
49
-
50
- false
51
- end
52
- private_class_method :compare?
53
-
54
- # E.g., > :col, we get comparator: >, args: col
55
- def self.comparison(comparator:, name:)
56
- function = COMPARE[comparator]
57
- Proc.with(type: :symbol, function: function[name])
58
- end
59
- private_class_method :comparison
60
-
61
- # @param (see Matchers::Matcher#matches?)
62
- # @return (see Matchers::Matcher#matches?)
63
- def self.matches?(cell)
64
- match = SYMBOL_COMPARE_RE.match(cell)
65
- return false unless match
66
-
67
- comparator = match['comparator'] || '='
68
- name = match['name'].to_sym
69
-
70
- comparison(comparator: comparator, name: name)
71
- end
72
- end
73
- end