ruy 0.0.1 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 003d024c6b2f05a3c015ccbd789efd59552fc7a7
4
- data.tar.gz: 411c3711fe45f4abdb16e92618cd7bc120dd17b8
3
+ metadata.gz: cb7f94655e005150da3e73788e1f3a9fd468a736
4
+ data.tar.gz: 69ef1d941e8316dddcf67559502c091abe7df1af
5
5
  SHA512:
6
- metadata.gz: 3872449535981b86aa3a2406ee61a1a3da36ff0b1eeb86fba96d73eab1efa96330b612c246dc684f5888b44e60ebfb9ebf741b0227ef9f18b9de05faefdc4cdb
7
- data.tar.gz: 2c825a71271a12b7c85d11743d66d70ef49adb96d959b810366b0002304bb595c76d6b72384ba5a4f711b645dd8d18098d58962fd81b966917a871746042a82f
6
+ metadata.gz: 21f385fc78e17bbb78dc68b26194574c08ed494f16f75b4fa37f570131c8d55aeec4bbc654bcef7b873c5651f5328b274def2f032edfe338c6acbf3edd6e1810
7
+ data.tar.gz: dd62cdfa7593eb95b43ded250262358f057fa277d583cb7750d04811cbcf116504121fba08d9b93f111c4634371efeb3004cb64c6d7916442802a23d1b6a1748
data/lib/ruy.rb ADDED
@@ -0,0 +1,131 @@
1
+ require_relative 'ruy/rule'
2
+ require_relative 'ruy/adapters'
3
+ require_relative 'ruy/conditions'
4
+ require_relative 'ruy/rule_storage'
5
+
6
+ module Ruy
7
+ class RuleSet < Rule
8
+
9
+ attr_reader :name
10
+ attr_reader :outcomes
11
+ attr_accessor :metadata
12
+
13
+ def initialize
14
+ super
15
+
16
+ @outcomes = []
17
+ @fallback = nil
18
+ @metadata = {}
19
+ end
20
+
21
+ def [](key)
22
+ @metadata[key]
23
+ end
24
+
25
+ def []=(key, value)
26
+ @metadata[key] = value
27
+ end
28
+
29
+ def call(ctx)
30
+ var_ctx = VariableContext.new(ctx, @vars)
31
+ if @apply = super(var_ctx)
32
+ compute_outcome(var_ctx)
33
+ else
34
+ @fallback
35
+ end
36
+ end
37
+
38
+ def apply?
39
+ @apply
40
+ end
41
+
42
+ def compute_outcome(var_ctx)
43
+ @outcomes.each do |outcome|
44
+ result = outcome.call(var_ctx)
45
+ unless result.nil?
46
+ return result
47
+ end
48
+ end
49
+
50
+ nil
51
+ end
52
+
53
+ def to_hash
54
+ if @outcomes.any?
55
+ super.merge({ outcomes: @outcomes.map { |o| o.to_hash } })
56
+ end
57
+ end
58
+
59
+ def fallback(value)
60
+ @fallback = value
61
+ end
62
+
63
+ def outcome(value, &block)
64
+ outcome = Outcome.new(value)
65
+
66
+ outcome.instance_exec(&block) if block_given?
67
+
68
+ @outcomes << outcome
69
+ end
70
+
71
+ def method_missing(m, *args, &block)
72
+ super
73
+ end
74
+ end
75
+
76
+ class Context < Hash
77
+ def self.from_hash(hash)
78
+ ctx = Context.new
79
+ ctx.merge!(hash)
80
+
81
+ ctx
82
+ end
83
+ end
84
+
85
+ class Outcome < Rule
86
+ attr_reader :value
87
+
88
+ def initialize(value)
89
+ super()
90
+
91
+ @value = value
92
+ @params = [@value]
93
+ end
94
+
95
+ def call(ctx)
96
+ if super(ctx)
97
+ @value
98
+ end
99
+ end
100
+
101
+ def ==(o)
102
+ o.kind_of?(Outcome) &&
103
+ value == o.value &&
104
+ conditions == o.conditions
105
+ end
106
+ end
107
+
108
+ # Context that can resolve variable access
109
+ class VariableContext
110
+ def initialize(ctx, vars)
111
+ @ctx = ctx
112
+ @vars = vars
113
+
114
+ @resolved_vars = {}
115
+ end
116
+
117
+ # Resolve the given attr from the variables or the context
118
+ # If attribute can't be resolved then throw an exception
119
+ #
120
+ # @param [Symbol] attr
121
+ # @return [Object]
122
+ def resolve(attr)
123
+ if @vars.include?(attr)
124
+ @resolved_vars[attr] ||= @ctx.instance_exec(&@vars[attr])
125
+ else
126
+ @ctx.fetch(attr) { |key| @ctx[key.to_s] }
127
+ end
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'adapters/file_adapter'
2
+ require_relative 'adapters/sequel_adapter'
3
+
4
+ module Ruy
5
+ module Adapters; end
6
+ end
@@ -0,0 +1,28 @@
1
+ module Ruy
2
+ module Adapters
3
+ class FileAdapter
4
+ #
5
+ # @param [String] directory
6
+ def initialize(directory)
7
+ @directory = directory
8
+ end
9
+
10
+ # Load all the rule files in the directory specified when the adapter
11
+ # was created
12
+ #
13
+ # @return [Array<Ruy::RuleSet]
14
+ def load_rules
15
+ rules = []
16
+
17
+ Dir.glob("#{@directory}/*.rb") do |rule_file|
18
+ rule_set = Ruy::RuleSet.new
19
+ rule_set.instance_eval(File.read(rule_file))
20
+
21
+ rules << rule_set
22
+ end
23
+
24
+ rules
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ require 'sequel'
2
+ require 'json'
3
+
4
+ module Ruy
5
+ module Adapters
6
+ class SequelAdapter
7
+ def initialize(connection_data)
8
+ @db = initialize_connection(connection_data)
9
+ end
10
+
11
+ # Load all the rule objects in the specified database.
12
+ #
13
+ # @return [Array<Ruy::RuleSet>]
14
+ def load_rules(params = {})
15
+ options = { rules_table: 'event_rules',
16
+ serialized_data_column: 'data' }.merge(params)
17
+
18
+ dataset = @db[options[:rules_table]].all
19
+ dataset.collect do |row|
20
+ rule_set = Ruy::RuleSet.from_hash(
21
+ JSON.parse(row[options[:serialized_data_column]], symbolize_names: true)
22
+ )
23
+
24
+ yield row, rule_set if block_given?
25
+ rule_set
26
+ end
27
+ end
28
+
29
+ private
30
+ #
31
+ # @param [Hash] connection_data
32
+ # @return []
33
+ def initialize_connection(connection_data)
34
+ Sequel.connect(adapter: connection_data[:adapter],
35
+ host: connection_data[:host], database: connection_data[:database],
36
+ user: connection_data[:user], password: connection_data[:password])
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'conditions/all'
2
+ require_relative 'conditions/any'
3
+ require_relative 'conditions/assert'
4
+ require_relative 'conditions/between'
5
+ require_relative 'conditions/cond'
6
+ require_relative 'conditions/eq'
7
+ require_relative 'conditions/except'
8
+ require_relative 'conditions/greater_than_or_equal'
9
+ require_relative 'conditions/include'
10
+ require_relative 'conditions/included'
11
+ require_relative 'conditions/less_than'
12
+ require_relative 'conditions/less_than_or_equal'
13
+
14
+ module Ruy
15
+ module Conditions; end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that all rules will succeed.
5
+ class All < Ruy::Rule
6
+ def call(var_ctx)
7
+ @conditions.all? do |condition|
8
+ condition.call(var_ctx)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that at least one of the rules will succeed.
5
+ class Any < Ruy::Rule
6
+ def call(var_ctx)
7
+ @conditions.any? do |condition|
8
+ condition.call(var_ctx)
9
+ end
10
+ end
11
+
12
+ def ==(o)
13
+ o.kind_of?(Any) &&
14
+ conditions == o.conditions
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Asserts that an attribute has a truth value.
5
+ class Assert < Ruy::Rule
6
+ attr_reader :attr
7
+
8
+ # @param attr Context attribute's name
9
+ def initialize(attr)
10
+ @attr = attr
11
+ @params = [@attr]
12
+ end
13
+
14
+ def call(var_ctx)
15
+ var_ctx.resolve(@attr)
16
+ end
17
+
18
+ def ==(o)
19
+ o.kind_of?(Assert) &&
20
+ @attr == o.attr
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context value belongs to a given range.
5
+ #
6
+ # Comparison formula: from <= context[attr] <= to
7
+ class Between < Ruy::Rule
8
+ attr_reader :attr, :from, :to
9
+
10
+ # @param attr Name of the attribute that will be evaluated
11
+ # @param from Range lower bound
12
+ # @param to Range upper bound
13
+ # @yield a block in the context of the current rule
14
+ def initialize(attr, from, to, &block)
15
+ super()
16
+
17
+ @attr = attr
18
+ @from = from
19
+ @to = to
20
+
21
+ @params = [@attr, @from, @to]
22
+
23
+ instance_exec(&block) if block_given?
24
+ end
25
+
26
+ def call(var_ctx)
27
+ value = var_ctx.resolve(@attr)
28
+ @from <= value && value <= @to && super
29
+ end
30
+
31
+ def ==(o)
32
+ o.kind_of?(Between) &&
33
+ @attr == o.attr &&
34
+ @from == o.from &&
35
+ @to == o.to &&
36
+ self.conditions == o.conditions
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects a successful evaluation of a sub-pair of rules.
5
+ #
6
+ # Groups rules in slices of 2 rules. Then evalutes each slice until one of them succeds.
7
+ # If there's an even number of rules, the last slice will only one rule.
8
+ #
9
+ # Cond is handy for mocking if/else if/else constructs.
10
+ class Cond < Ruy::Rule
11
+ def call(var_ctx)
12
+ clauses = @conditions.each_slice(2)
13
+
14
+ clauses.any? do |rule_1, rule_2|
15
+ result = rule_1.call(var_ctx)
16
+
17
+ if rule_2
18
+ result && rule_2.call(var_ctx)
19
+ else
20
+ result
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute will be equal to a given value.
5
+ #
6
+ class Eq < Ruy::Rule
7
+ attr_reader :attr, :value
8
+
9
+ # @param attr Context attribute's name
10
+ # @param value Expected value
11
+ def initialize(attr, value)
12
+ super()
13
+
14
+ @attr = attr
15
+ @value = value
16
+ @params = [@attr, @value]
17
+ end
18
+
19
+ def call(var_ctx)
20
+ var_ctx.resolve(@attr) == @value
21
+ end
22
+
23
+ def ==(o)
24
+ o.kind_of?(Eq) &&
25
+ attr == o.attr &&
26
+ value == o.value
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a condition is not met.
5
+ #
6
+ # When a sub-rule is given, Except will expect an unsuccessful evaluation of that sub-rule.
7
+ # When a sub-rule is not given, Except will expect a context attribute is not equal to a given
8
+ # value.
9
+ class Except < Ruy::Rule
10
+ attr_reader :attr, :value
11
+
12
+ # @param attr Context attribute's name
13
+ # @param value Non-expected value
14
+ # @yield a block in the context of the current rule
15
+ def initialize(attr = nil, value = nil, &block)
16
+ super()
17
+
18
+ @attr = attr
19
+ @value = value
20
+
21
+ @params = [@attr, @value]
22
+
23
+ if block_given?
24
+ instance_exec(&block)
25
+ end
26
+ end
27
+
28
+ def call(var_ctx)
29
+ result = true
30
+
31
+ if @attr
32
+ result &&= var_ctx.resolve(@attr) != @value
33
+ end
34
+
35
+ if self.conditions.any?
36
+ result &&= !super(var_ctx)
37
+ end
38
+
39
+ result
40
+ end
41
+
42
+ def ==(o)
43
+ o.kind_of?(Except) &&
44
+ @attr == o.attr &&
45
+ @value == o.value &&
46
+ @conditions == o.conditions
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,34 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute will be greater than or equal to the given value.
5
+ class GreaterThanOrEqual < Ruy::Rule
6
+ attr_reader :attr, :value
7
+
8
+ # @param attr Context attribute's name
9
+ # @param value
10
+ # @yield a block in the context of the current rule
11
+ def initialize(attr, value, &block)
12
+ super()
13
+
14
+ @attr = attr
15
+ @value = value
16
+
17
+ @params = [@attr, @value]
18
+
19
+ instance_exec(&block) if block_given?
20
+ end
21
+
22
+ def call(var_ctx)
23
+ var_ctx.resolve(@attr) >= @value && super
24
+ end
25
+
26
+ def ==(o)
27
+ o.kind_of?(GreaterThanOrEqual) &&
28
+ attr == o.attr &&
29
+ value == o.value &&
30
+ self.conditions == o.conditions
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute is included in a set of values.
5
+ class Include < Ruy::Rule
6
+ attr_reader :attr, :values
7
+
8
+ # @param attr Context attribute's name
9
+ # @param values Expected set of values
10
+ # @yield a block in the context of the current rule
11
+ def initialize(attr, values, &block)
12
+ super()
13
+
14
+ @attr = attr
15
+ @values = values
16
+
17
+ @params = [@attr, @values]
18
+
19
+ instance_exec(&block) if block_given?
20
+ end
21
+
22
+ def call(var_ctx)
23
+ self.values.include?(var_ctx.resolve(self.attr)) && super
24
+ end
25
+
26
+ def ==(o)
27
+ o.kind_of?(Include) &&
28
+ self.attr == o.attr &&
29
+ self.values == o.values &&
30
+ self.conditions == o.conditions
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a value is included in a set of values from the context attribute.
5
+ class Included < Ruy::Rule
6
+ attr_reader :attr, :value
7
+
8
+ # @param attr Context attribute's name
9
+ # @param value Expected set of values
10
+ # @yield a block in the context of the current rule
11
+ def initialize(attr, value, &block)
12
+ super()
13
+
14
+ @attr = attr
15
+ @value = value
16
+
17
+ @params = [@attr, @value]
18
+
19
+ instance_exec(&block) if block_given?
20
+ end
21
+
22
+ def call(var_ctx)
23
+ var_ctx.resolve(self.attr).include?(self.value) && super
24
+ end
25
+
26
+ def ==(o)
27
+ o.kind_of?(Included) &&
28
+ self.attr == o.attr &&
29
+ self.value == o.value &&
30
+ self.conditions == o.conditions
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute will be less than given value.
5
+ class LessThan < Ruy::Rule
6
+ attr_reader :attr, :value
7
+
8
+ # @param attr Context attribute's name
9
+ # @param value
10
+ def initialize(attr, value)
11
+ @attr = attr
12
+ @value = value
13
+
14
+ @params = [@attr, @value]
15
+ end
16
+
17
+ def call(var_ctx)
18
+ var_ctx.resolve(@attr) < @value
19
+ end
20
+
21
+ def ==(o)
22
+ o.kind_of?(LessThan) &&
23
+ attr == o.attr &&
24
+ value == o.value
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module Ruy
2
+ module Conditions
3
+
4
+ # Expects that a context attribute will be less than or equal to the given value.
5
+ class LessThanOrEqual < Ruy::Rule
6
+ attr_reader :attr, :value
7
+
8
+ # @param attr Context attribute's name
9
+ # @param value
10
+ def initialize(attr, value)
11
+ @attr = attr
12
+ @value = value
13
+
14
+ @params = [@attr, @value]
15
+ end
16
+
17
+ def call(var_ctx)
18
+ var_ctx.resolve(@attr) <= @value
19
+ end
20
+
21
+ def ==(o)
22
+ o.kind_of?(LessThanOrEqual) &&
23
+ attr == o.attr &&
24
+ value == o.value
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/ruy/rule.rb ADDED
@@ -0,0 +1,219 @@
1
+ module Ruy
2
+
3
+ # Returns a constant using a qualified constant name string
4
+ #
5
+ # @param [String] name
6
+ # @return [Object]
7
+ def self.qualified_const_get(name)
8
+ root = Object
9
+ name.split('::').each do |klass|
10
+ root = root.const_get(klass)
11
+ end
12
+
13
+ root
14
+ end
15
+
16
+ # A rule is a set of conditions
17
+ class Rule
18
+
19
+ attr_reader :conditions
20
+ attr_reader :vars
21
+
22
+ def initialize
23
+ @conditions = []
24
+ @vars = {}
25
+ @attrs = {}
26
+ @params = []
27
+ end
28
+
29
+ # Serialize a rule object as a hash
30
+ #
31
+ # @return [Hash]
32
+ def to_hash
33
+ ret = { node: self.class.name, params: params }
34
+ ret[:conditions] = @conditions.map(&:to_hash) if @conditions.any?
35
+
36
+ ret
37
+ end
38
+
39
+ # Look to the given keys, and load the rule nodes in their values
40
+ #
41
+ # @param [Array<Symbol>] keys
42
+ # @param [Hash] hash
43
+ # @return [Ruy::Rule]
44
+ def load_rule_objects_from(hash, *keys)
45
+ keys.each do |key|
46
+ if hash.has_key?(key)
47
+ hash[key].each { |o| self.send(key) << Ruy::Rule.from_hash(o) }
48
+ end
49
+ end
50
+
51
+ self
52
+ end
53
+
54
+ # Load a new role from it hash representation
55
+ #
56
+ # @param [Hash] hash
57
+ # @return [Ruy::Rule]
58
+ def self.from_hash(hash)
59
+ rule = Ruy.qualified_const_get(hash[:node]).new(*hash[:params])
60
+ rule.load_rule_objects_from(hash, :conditions, :outcomes)
61
+ end
62
+
63
+ # Adds an All condition.
64
+ #
65
+ # @yield Evaluates the given block in the context of the current rule
66
+ def all(&block)
67
+ cond = Conditions::All.new
68
+ cond.instance_exec(&block)
69
+
70
+ @conditions << cond
71
+ end
72
+
73
+ # Adds an Any condition.
74
+ #
75
+ # @yield Evaluates the given block in the context of the current rule
76
+ def any(&block)
77
+ cond = Conditions::Any.new
78
+ cond.instance_exec(&block)
79
+
80
+ @conditions << cond
81
+ end
82
+
83
+ # Adds an Assert condition.
84
+ #
85
+ # @param (see Conditions::Assert#initialize)
86
+ def assert(attr)
87
+ @conditions << Conditions::Assert.new(attr)
88
+ end
89
+
90
+ # Adds a Between condition.
91
+ #
92
+ # @param (see Conditions::Between#initialize)
93
+ def between(attr, from, to, &block)
94
+ @conditions << Conditions::Between.new(attr, from, to, &block)
95
+ end
96
+
97
+ # Adds an Eq condition.
98
+ #
99
+ # @param (see Conditions::Eq#initialize)
100
+ def eq(attr, value, &block)
101
+ @conditions << Conditions::Eq.new(attr, value, &block)
102
+ end
103
+
104
+ # Adds a Cond condition.
105
+ #
106
+ # @yield Evaluates the given block in the context of the current rule
107
+ def cond(&block)
108
+ cond = Conditions::Cond.new
109
+ cond.instance_exec(&block)
110
+
111
+ @conditions << cond
112
+ end
113
+
114
+ # Adds an Except condition.
115
+ #
116
+ # @param (see Conditions::Except#initialize)
117
+ def except(attr = nil, value = nil, &block)
118
+ @conditions << Conditions::Except.new(attr, value, &block)
119
+ end
120
+
121
+ # Adds a GreaterThanOrEqual condition.
122
+ #
123
+ # @param (see Conditions::GreaterThanOrEqual#initialize)
124
+ def greater_than_or_equal(attr, value)
125
+ @conditions << Conditions::GreaterThanOrEqual.new(attr, value)
126
+ end
127
+
128
+ # Adds an Include condition.
129
+ #
130
+ # @param (see Conditions::Include#initialize)
131
+ def include(attr, values, &block)
132
+ @conditions << Conditions::Include.new(attr, values, &block)
133
+ end
134
+
135
+ # Adds an Included condition.
136
+ #
137
+ # @param (see Conditions::Included#initialize)
138
+ def included(attr, value, &block)
139
+ @conditions << Conditions::Included.new(attr, value, &block)
140
+ end
141
+
142
+ # Adds a LessOrEqualThan condition.
143
+ #
144
+ # @param (see Conditions::LessOrEqualThan#initialize)
145
+ def less_than_or_equal(attr, value, &block)
146
+ @conditions << Conditions::LessThanOrEqual.new(attr, value)
147
+ end
148
+
149
+ # Adds a LessThan condition.
150
+ #
151
+ # @param (see Conditions::LessThan#initialize)
152
+ def less_than(attr, value)
153
+ @conditions << Conditions::LessThan.new(attr, value)
154
+ end
155
+
156
+ # Gets attribute's value from the given name.
157
+ #
158
+ # @param name
159
+ #
160
+ # @return The attribute's value.
161
+ def get(name)
162
+ @attrs[name]
163
+ end
164
+
165
+ # Sets a custom attribute.
166
+ #
167
+ # @param name Attribute's name
168
+ # @param value Attribute's value
169
+ def set(name, value)
170
+ @attrs[name] = value
171
+ end
172
+
173
+ # Defines a variable.
174
+ #
175
+ # If both value and block are given, only the block will be taken into account.
176
+ #
177
+ # @param name The name of the variable
178
+ # @param value The value of the variable
179
+ #
180
+ # @yield a block that will resolve the variable's value
181
+ def var(name, value = nil, &block)
182
+ if block_given?
183
+ @vars[name] = block
184
+ else
185
+ @vars[name] = lambda { value }
186
+ end
187
+ end
188
+
189
+ # Evaluates all conditions.
190
+ #
191
+ # @return [true] When all conditions succeeds
192
+ # @return [false] Otherwise
193
+ def call(ctx)
194
+ success = @conditions.take_while do |condition|
195
+ condition.call(ctx)
196
+ end
197
+
198
+ success.length == @conditions.length
199
+ rescue NoMethodError
200
+ false
201
+ end
202
+
203
+ def ==(o)
204
+ o.kind_of?(Rule) &&
205
+ conditions == o.conditions &&
206
+ vars.keys == o.vars.keys
207
+ end
208
+
209
+ private
210
+
211
+ # Getter method for rules params. It returns all the params without nil objects
212
+ #
213
+ # @return [Array<Object>]
214
+ def params
215
+ @params.compact
216
+ end
217
+
218
+ end
219
+ end
@@ -0,0 +1,36 @@
1
+ module Ruy
2
+ class RuleStorage
3
+ attr_writer :adapter
4
+
5
+ def initialize(adapter, rules = [])
6
+ @adapter = adapter
7
+ @rules = rules
8
+ end
9
+
10
+ # Evaluate the given context against all the loaded rules
11
+ #
12
+ # @param [Hash] ctx
13
+ # @return [Array<Object>]
14
+ def evaluate_all(ctx)
15
+ @rules.map { |rule| rule.call(ctx) }.compact
16
+ end
17
+
18
+ # The first rule that apply will return the method
19
+ #
20
+ # @param [Hash] ctx
21
+ # @return [Object]
22
+ def evaluate_first(ctx)
23
+ @rules.each do |rule|
24
+ result = rule.call(ctx)
25
+ return result if rule.apply?
26
+ end
27
+ end
28
+
29
+ # Load all the rules from the adapter
30
+ #
31
+ def load_rules(params = {}, &block)
32
+ @rules = @adapter.load_rules(params, &block)
33
+ end
34
+ alias_method :relaod, :load_rules
35
+ end
36
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moove-IT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2014-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,14 +24,46 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sequel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 4.12.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 4.12.0
27
41
  description:
28
42
  email:
29
43
  executables: []
30
44
  extensions: []
31
45
  extra_rdoc_files: []
32
46
  files:
33
- - README.md
34
- homepage:
47
+ - lib/ruy/adapters/file_adapter.rb
48
+ - lib/ruy/adapters/sequel_adapter.rb
49
+ - lib/ruy/adapters.rb
50
+ - lib/ruy/conditions/all.rb
51
+ - lib/ruy/conditions/any.rb
52
+ - lib/ruy/conditions/assert.rb
53
+ - lib/ruy/conditions/between.rb
54
+ - lib/ruy/conditions/cond.rb
55
+ - lib/ruy/conditions/eq.rb
56
+ - lib/ruy/conditions/except.rb
57
+ - lib/ruy/conditions/greater_than_or_equal.rb
58
+ - lib/ruy/conditions/include.rb
59
+ - lib/ruy/conditions/included.rb
60
+ - lib/ruy/conditions/less_than.rb
61
+ - lib/ruy/conditions/less_than_or_equal.rb
62
+ - lib/ruy/conditions.rb
63
+ - lib/ruy/rule.rb
64
+ - lib/ruy/rule_storage.rb
65
+ - lib/ruy.rb
66
+ homepage: https://github.com/Moove-it/ruy
35
67
  licenses:
36
68
  - MIT
37
69
  metadata: {}
data/README.md DELETED
@@ -1 +0,0 @@
1
- ruy comming soon