dry-logic 1.0.5 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +122 -26
- data/LICENSE +1 -1
- data/README.md +12 -14
- data/dry-logic.gemspec +26 -20
- data/lib/dry-logic.rb +1 -1
- data/lib/dry/logic.rb +2 -2
- data/lib/dry/logic/evaluator.rb +1 -1
- data/lib/dry/logic/operations.rb +11 -11
- data/lib/dry/logic/operations/abstract.rb +3 -3
- data/lib/dry/logic/operations/and.rb +3 -3
- data/lib/dry/logic/operations/attr.rb +1 -1
- data/lib/dry/logic/operations/binary.rb +4 -3
- data/lib/dry/logic/operations/check.rb +4 -4
- data/lib/dry/logic/operations/each.rb +2 -2
- data/lib/dry/logic/operations/implication.rb +2 -2
- data/lib/dry/logic/operations/key.rb +3 -3
- data/lib/dry/logic/operations/negation.rb +2 -2
- data/lib/dry/logic/operations/or.rb +2 -2
- data/lib/dry/logic/operations/set.rb +3 -3
- data/lib/dry/logic/operations/unary.rb +1 -1
- data/lib/dry/logic/operations/xor.rb +2 -2
- data/lib/dry/logic/operators.rb +4 -4
- data/lib/dry/logic/predicates.rb +32 -7
- data/lib/dry/logic/result.rb +2 -2
- data/lib/dry/logic/rule.rb +8 -8
- data/lib/dry/logic/rule/interface.rb +32 -37
- data/lib/dry/logic/rule/predicate.rb +3 -3
- data/lib/dry/logic/rule_compiler.rb +3 -3
- data/lib/dry/logic/version.rb +1 -1
- metadata +17 -166
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -34
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -70
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -9
- data/.rspec +0 -4
- data/.rubocop.yml +0 -89
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -16
- data/Rakefile +0 -14
- data/benchmarks/rule_application.rb +0 -30
- data/benchmarks/setup.rb +0 -13
- data/bin/console +0 -11
- data/docsite/source/index.html.md +0 -54
- data/docsite/source/operations.html.md +0 -62
- data/docsite/source/predicates.html.md +0 -102
- data/examples/basic.rb +0 -16
- data/spec/integration/result_spec.rb +0 -61
- data/spec/integration/rule_spec.rb +0 -55
- data/spec/shared/predicates.rb +0 -59
- data/spec/shared/rule.rb +0 -74
- data/spec/spec_helper.rb +0 -30
- data/spec/support/mutant.rb +0 -11
- data/spec/unit/operations/and_spec.rb +0 -70
- data/spec/unit/operations/attr_spec.rb +0 -29
- data/spec/unit/operations/check_spec.rb +0 -51
- data/spec/unit/operations/each_spec.rb +0 -49
- data/spec/unit/operations/implication_spec.rb +0 -32
- data/spec/unit/operations/key_spec.rb +0 -135
- data/spec/unit/operations/negation_spec.rb +0 -51
- data/spec/unit/operations/or_spec.rb +0 -75
- data/spec/unit/operations/set_spec.rb +0 -43
- data/spec/unit/operations/xor_spec.rb +0 -63
- data/spec/unit/predicates/array_spec.rb +0 -43
- data/spec/unit/predicates/attr_spec.rb +0 -31
- data/spec/unit/predicates/bool_spec.rb +0 -36
- data/spec/unit/predicates/bytesize_spec.rb +0 -48
- data/spec/unit/predicates/case_spec.rb +0 -35
- data/spec/unit/predicates/date_spec.rb +0 -33
- data/spec/unit/predicates/date_time_spec.rb +0 -33
- data/spec/unit/predicates/decimal_spec.rb +0 -34
- data/spec/unit/predicates/empty_spec.rb +0 -40
- data/spec/unit/predicates/eql_spec.rb +0 -23
- data/spec/unit/predicates/even_spec.rb +0 -33
- data/spec/unit/predicates/excluded_from_spec.rb +0 -37
- data/spec/unit/predicates/excludes_spec.rb +0 -58
- data/spec/unit/predicates/false_spec.rb +0 -37
- data/spec/unit/predicates/filled_spec.rb +0 -40
- data/spec/unit/predicates/float_spec.rb +0 -33
- data/spec/unit/predicates/format_spec.rb +0 -31
- data/spec/unit/predicates/gt_spec.rb +0 -42
- data/spec/unit/predicates/gteq_spec.rb +0 -42
- data/spec/unit/predicates/hash_spec.rb +0 -40
- data/spec/unit/predicates/included_in_spec.rb +0 -37
- data/spec/unit/predicates/includes_spec.rb +0 -24
- data/spec/unit/predicates/int_spec.rb +0 -36
- data/spec/unit/predicates/key_spec.rb +0 -31
- data/spec/unit/predicates/lt_spec.rb +0 -42
- data/spec/unit/predicates/lteq_spec.rb +0 -42
- data/spec/unit/predicates/max_bytesize_spec.rb +0 -39
- data/spec/unit/predicates/max_size_spec.rb +0 -51
- data/spec/unit/predicates/min_bytesize_spec.rb +0 -39
- data/spec/unit/predicates/min_size_spec.rb +0 -51
- data/spec/unit/predicates/none_spec.rb +0 -30
- data/spec/unit/predicates/not_eql_spec.rb +0 -23
- data/spec/unit/predicates/number_spec.rb +0 -39
- data/spec/unit/predicates/odd_spec.rb +0 -33
- data/spec/unit/predicates/respond_to_spec.rb +0 -31
- data/spec/unit/predicates/size_spec.rb +0 -57
- data/spec/unit/predicates/str_spec.rb +0 -34
- data/spec/unit/predicates/time_spec.rb +0 -33
- data/spec/unit/predicates/true_spec.rb +0 -37
- data/spec/unit/predicates/type_spec.rb +0 -37
- data/spec/unit/predicates/uuid_v4_spec.rb +0 -29
- data/spec/unit/predicates_spec.rb +0 -25
- data/spec/unit/rule/predicate_spec.rb +0 -55
- data/spec/unit/rule_compiler_spec.rb +0 -129
- data/spec/unit/rule_spec.rb +0 -213
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/logic/operations/binary"
|
4
|
+
require "dry/logic/result"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Logic
|
@@ -17,7 +17,7 @@ module Dry
|
|
17
17
|
def type
|
18
18
|
:and
|
19
19
|
end
|
20
|
-
|
20
|
+
alias_method :operator, :type
|
21
21
|
|
22
22
|
def call(input)
|
23
23
|
left_result = left.(input)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/logic/operations/abstract"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Logic
|
@@ -10,9 +10,10 @@ module Dry
|
|
10
10
|
|
11
11
|
attr_reader :right
|
12
12
|
|
13
|
-
def initialize(
|
13
|
+
def initialize(left, right, **options)
|
14
14
|
super
|
15
|
-
@left
|
15
|
+
@left = left
|
16
|
+
@right = right
|
16
17
|
end
|
17
18
|
|
18
19
|
def ast(input = Undefined)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/logic/operations/unary"
|
4
|
+
require "dry/logic/evaluator"
|
5
|
+
require "dry/logic/result"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Logic
|
@@ -12,7 +12,7 @@ module Dry
|
|
12
12
|
|
13
13
|
def self.new(rule, **options)
|
14
14
|
if options[:evaluator]
|
15
|
-
super(rule, options)
|
15
|
+
super(rule, **options)
|
16
16
|
else
|
17
17
|
keys = options.fetch(:keys)
|
18
18
|
evaluator = Evaluator::Set.new(keys)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/logic/operations/unary"
|
4
|
+
require "dry/logic/evaluator"
|
5
|
+
require "dry/logic/result"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Logic
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/logic/operations/abstract"
|
4
|
+
require "dry/logic/result"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Logic
|
@@ -29,7 +29,7 @@ module Dry
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def to_s
|
32
|
-
"#{type}(#{rules.map(&:to_s).join(
|
32
|
+
"#{type}(#{rules.map(&:to_s).join(", ")})"
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
data/lib/dry/logic/operators.rb
CHANGED
@@ -6,22 +6,22 @@ module Dry
|
|
6
6
|
def and(other)
|
7
7
|
Operations::And.new(self, other)
|
8
8
|
end
|
9
|
-
|
9
|
+
alias_method :&, :and
|
10
10
|
|
11
11
|
def or(other)
|
12
12
|
Operations::Or.new(self, other)
|
13
13
|
end
|
14
|
-
|
14
|
+
alias_method :|, :or
|
15
15
|
|
16
16
|
def xor(other)
|
17
17
|
Operations::Xor.new(self, other)
|
18
18
|
end
|
19
|
-
|
19
|
+
alias_method :^, :xor
|
20
20
|
|
21
21
|
def then(other)
|
22
22
|
Operations::Implication.new(self, other)
|
23
23
|
end
|
24
|
-
|
24
|
+
alias_method :>, :then
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/dry/logic/predicates.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "bigdecimal"
|
4
|
+
require "bigdecimal/util"
|
5
|
+
require "date"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Logic
|
@@ -13,7 +13,7 @@ module Dry
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def type?(type, input)
|
16
|
-
input.
|
16
|
+
input.is_a?(type)
|
17
17
|
end
|
18
18
|
|
19
19
|
def nil?(input)
|
@@ -147,12 +147,12 @@ module Dry
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def inclusion?(list, input)
|
150
|
-
::Kernel.warn
|
150
|
+
::Kernel.warn "inclusion is deprecated - use included_in instead."
|
151
151
|
included_in?(list, input)
|
152
152
|
end
|
153
153
|
|
154
154
|
def exclusion?(list, input)
|
155
|
-
::Kernel.warn
|
155
|
+
::Kernel.warn "exclusion is deprecated - use excluded_from instead."
|
156
156
|
excluded_from?(list, input)
|
157
157
|
end
|
158
158
|
|
@@ -206,11 +206,36 @@ module Dry
|
|
206
206
|
pattern === input
|
207
207
|
end
|
208
208
|
|
209
|
+
def uuid_v1?(input)
|
210
|
+
uuid_v1_format = /\A[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
|
211
|
+
format?(uuid_v1_format, input)
|
212
|
+
end
|
213
|
+
|
214
|
+
def uuid_v2?(input)
|
215
|
+
uuid_v2_format = /\A[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
|
216
|
+
format?(uuid_v2_format, input)
|
217
|
+
end
|
218
|
+
|
219
|
+
def uuid_v3?(input)
|
220
|
+
uuid_v3_format = /\A[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
|
221
|
+
format?(uuid_v3_format, input)
|
222
|
+
end
|
223
|
+
|
209
224
|
def uuid_v4?(input)
|
210
|
-
uuid_v4_format =
|
225
|
+
uuid_v4_format = /\A[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
|
211
226
|
format?(uuid_v4_format, input)
|
212
227
|
end
|
213
228
|
|
229
|
+
def uuid_v5?(input)
|
230
|
+
uuid_v5_format = /\A[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
|
231
|
+
format?(uuid_v5_format, input)
|
232
|
+
end
|
233
|
+
|
234
|
+
def uri?(schemes, input)
|
235
|
+
uri_format = URI::DEFAULT_PARSER.make_regexp(schemes)
|
236
|
+
format?(uri_format, input)
|
237
|
+
end
|
238
|
+
|
214
239
|
def respond_to?(method, input)
|
215
240
|
input.respond_to?(method)
|
216
241
|
end
|
data/lib/dry/logic/result.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/constants"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Logic
|
@@ -69,7 +69,7 @@ module Dry
|
|
69
69
|
if args.empty?
|
70
70
|
name.to_s
|
71
71
|
else
|
72
|
-
"#{name}(#{args.map(&:last).map(&:inspect).join(
|
72
|
+
"#{name}(#{args.map(&:last).map(&:inspect).join(", ")})"
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
data/lib/dry/logic/rule.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "concurrent/map"
|
4
|
+
require "dry/core/constants"
|
5
|
+
require "dry/core/equalizer"
|
6
|
+
require "dry/logic/operations"
|
7
|
+
require "dry/logic/result"
|
8
|
+
require "dry/logic/rule/interface"
|
9
9
|
|
10
10
|
module Dry
|
11
11
|
module Logic
|
@@ -38,13 +38,13 @@ module Dry
|
|
38
38
|
base.interfaces.fetch_or_store([arity, curried]) do
|
39
39
|
interface = Interface.new(arity, curried)
|
40
40
|
klass = Class.new(base) { include interface }
|
41
|
-
base.const_set("#{base.name.split(
|
41
|
+
base.const_set("#{base.name.split("::").last}#{interface.name}", klass)
|
42
42
|
klass
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.build(predicate, args: EMPTY_ARRAY, arity: predicate.arity, **options)
|
47
|
-
specialize(arity, args.size).new(predicate, {
|
47
|
+
specialize(arity, args.size).new(predicate, {args: args, arity: arity, **options})
|
48
48
|
end
|
49
49
|
|
50
50
|
def initialize(predicate, options = EMPTY_HASH)
|
@@ -4,6 +4,8 @@ module Dry
|
|
4
4
|
module Logic
|
5
5
|
class Rule
|
6
6
|
class Interface < ::Module
|
7
|
+
SPLAT = ["*rest"].freeze
|
8
|
+
|
7
9
|
attr_reader :arity
|
8
10
|
|
9
11
|
attr_reader :curried
|
@@ -18,12 +20,10 @@ module Dry
|
|
18
20
|
|
19
21
|
define_constructor if curried?
|
20
22
|
|
21
|
-
if
|
22
|
-
define_splat_application
|
23
|
-
elsif constant?
|
23
|
+
if constant?
|
24
24
|
define_constant_application
|
25
25
|
else
|
26
|
-
|
26
|
+
define_application
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -32,7 +32,7 @@ module Dry
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def variable_arity?
|
35
|
-
arity.
|
35
|
+
arity.negative?
|
36
36
|
end
|
37
37
|
|
38
38
|
def curried?
|
@@ -41,7 +41,13 @@ module Dry
|
|
41
41
|
|
42
42
|
def unapplied
|
43
43
|
if variable_arity?
|
44
|
-
-1
|
44
|
+
unapplied = arity.abs - 1 - curried
|
45
|
+
|
46
|
+
if unapplied.negative?
|
47
|
+
0
|
48
|
+
else
|
49
|
+
unapplied
|
50
|
+
end
|
45
51
|
else
|
46
52
|
arity - curried
|
47
53
|
end
|
@@ -49,10 +55,21 @@ module Dry
|
|
49
55
|
|
50
56
|
def name
|
51
57
|
if constant?
|
52
|
-
|
58
|
+
"Constant"
|
53
59
|
else
|
54
|
-
arity_str =
|
55
|
-
|
60
|
+
arity_str =
|
61
|
+
if variable_arity?
|
62
|
+
"Variable#{arity.abs - 1}Arity"
|
63
|
+
else
|
64
|
+
"#{arity}Arity"
|
65
|
+
end
|
66
|
+
|
67
|
+
curried_str =
|
68
|
+
if curried?
|
69
|
+
"#{curried}Curried"
|
70
|
+
else
|
71
|
+
EMPTY_STRING
|
72
|
+
end
|
56
73
|
|
57
74
|
"#{arity_str}#{curried_str}"
|
58
75
|
end
|
@@ -61,9 +78,9 @@ module Dry
|
|
61
78
|
def define_constructor
|
62
79
|
assignment =
|
63
80
|
if curried.equal?(1)
|
64
|
-
|
81
|
+
"@arg0 = @args[0]"
|
65
82
|
else
|
66
|
-
"#{curried_args.join(
|
83
|
+
"#{curried_args.join(", ")} = @args"
|
67
84
|
end
|
68
85
|
|
69
86
|
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
@@ -91,32 +108,10 @@ module Dry
|
|
91
108
|
end
|
92
109
|
end
|
93
110
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
else
|
99
|
-
'@predicate[*input]'
|
100
|
-
end
|
101
|
-
|
102
|
-
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
103
|
-
def call(*input)
|
104
|
-
if #{application}
|
105
|
-
Result::SUCCESS
|
106
|
-
else
|
107
|
-
Result.new(false, id) { ast(*input) }
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def [](*input)
|
112
|
-
#{application}
|
113
|
-
end
|
114
|
-
RUBY
|
115
|
-
end
|
116
|
-
|
117
|
-
def define_fixed_application
|
118
|
-
parameters = unapplied_args.join(', ')
|
119
|
-
application = "@predicate[#{ (curried_args + unapplied_args).join(', ') }]"
|
111
|
+
def define_application
|
112
|
+
splat = variable_arity? ? SPLAT : EMPTY_ARRAY
|
113
|
+
parameters = (unapplied_args + splat).join(", ")
|
114
|
+
application = "@predicate[#{(curried_args + unapplied_args + splat).join(", ")}]"
|
120
115
|
|
121
116
|
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
122
117
|
def call(#{parameters})
|