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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +112 -93
- data/benchmarks/rufus_decision.rb +9 -1
- data/csv_decision.gemspec +6 -6
- data/doc/CSVDecision.html +54 -90
- data/doc/CSVDecision/CellValidationError.html +1 -1
- data/doc/CSVDecision/Columns.html +104 -45
- data/doc/CSVDecision/Columns/Dictionary.html +40 -24
- data/doc/CSVDecision/Columns/Entry.html +209 -22
- data/doc/CSVDecision/Constant.html +9 -50
- data/doc/CSVDecision/Data.html +182 -47
- data/doc/CSVDecision/Decide.html +97 -93
- data/doc/CSVDecision/Decision.html +105 -294
- data/doc/CSVDecision/Error.html +1 -1
- data/doc/CSVDecision/FileError.html +1 -1
- data/doc/CSVDecision/Function.html +18 -7
- data/doc/CSVDecision/Guard.html +245 -0
- data/doc/CSVDecision/Header.html +58 -50
- data/doc/CSVDecision/Input.html +20 -12
- data/doc/CSVDecision/Load.html +80 -14
- data/doc/CSVDecision/Matchers.html +237 -279
- data/doc/CSVDecision/Matchers/Constant.html +280 -13
- data/doc/CSVDecision/Matchers/Function.html +188 -19
- data/doc/CSVDecision/Matchers/Guard.html +568 -0
- data/doc/CSVDecision/Matchers/Matcher.html +200 -14
- data/doc/CSVDecision/Matchers/Numeric.html +165 -13
- data/doc/CSVDecision/Matchers/Pattern.html +56 -163
- data/doc/CSVDecision/Matchers/Range.html +48 -37
- data/doc/CSVDecision/Matchers/Symbol.html +161 -16
- data/doc/CSVDecision/Numeric.html +4 -4
- data/doc/CSVDecision/Options.html +53 -55
- data/doc/CSVDecision/Parse.html +23 -13
- data/doc/CSVDecision/ScanRow.html +461 -73
- data/doc/CSVDecision/Symbol.html +4 -4
- data/doc/CSVDecision/Table.html +185 -79
- data/doc/_index.html +15 -28
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +105 -82
- data/doc/index.html +105 -82
- data/doc/method_list.html +137 -113
- data/doc/top-level-namespace.html +1 -1
- data/lib/csv_decision.rb +2 -5
- data/lib/csv_decision/columns.rb +14 -5
- data/lib/csv_decision/data.rb +24 -6
- data/lib/csv_decision/decide.rb +18 -20
- data/lib/csv_decision/decision.rb +106 -42
- data/lib/csv_decision/header.rb +44 -23
- data/lib/csv_decision/input.rb +4 -2
- data/lib/csv_decision/load.rb +7 -3
- data/lib/csv_decision/matchers.rb +49 -41
- data/lib/csv_decision/matchers/constant.rb +62 -4
- data/lib/csv_decision/matchers/function.rb +33 -2
- data/lib/csv_decision/matchers/guard.rb +143 -0
- data/lib/csv_decision/matchers/numeric.rb +34 -3
- data/lib/csv_decision/matchers/pattern.rb +11 -4
- data/lib/csv_decision/matchers/range.rb +34 -26
- data/lib/csv_decision/matchers/symbol.rb +71 -5
- data/lib/csv_decision/options.rb +31 -20
- data/lib/csv_decision/parse.rb +28 -9
- data/lib/csv_decision/scan_row.rb +79 -13
- data/lib/csv_decision/table.rb +34 -23
- data/spec/csv_decision/columns_spec.rb +32 -7
- data/spec/csv_decision/constant_spec.rb +2 -26
- data/spec/csv_decision/decision_spec.rb +0 -9
- data/spec/csv_decision/examples_spec.rb +33 -16
- data/spec/csv_decision/matchers/function_spec.rb +1 -1
- data/spec/csv_decision/matchers/guard_spec.rb +153 -0
- data/spec/csv_decision/matchers/numeric_spec.rb +1 -1
- data/spec/csv_decision/matchers/pattern_spec.rb +2 -2
- data/spec/csv_decision/matchers/range_spec.rb +2 -2
- data/spec/csv_decision/matchers/symbol_spec.rb +1 -1
- data/spec/csv_decision/options_spec.rb +3 -3
- data/spec/csv_decision/table_spec.rb +96 -12
- data/spec/data/valid/benchmark_regexp.csv +10 -0
- data/spec/data/valid/regular_expressions.csv +11 -0
- metadata +14 -9
- data/lib/csv_decision/constant.rb +0 -54
- data/lib/csv_decision/function.rb +0 -32
- data/lib/csv_decision/numeric.rb +0 -38
- data/lib/csv_decision/symbol.rb +0 -73
data/lib/csv_decision/numeric.rb
DELETED
|
@@ -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
|
data/lib/csv_decision/symbol.rb
DELETED
|
@@ -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
|