ruy 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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