ruy 0.2.0 → 0.2.1

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: cd5ceb75eb7454f4c8b8477a9f57428c9d4c5a2a
4
- data.tar.gz: 84566c136caaa90dc3b9b237d27edc6c60af8adc
3
+ metadata.gz: 1892173ce87ec0352f8eb0058be130276ac3992d
4
+ data.tar.gz: 56e8ecb959603b387278c3c7b771eace0cd797dd
5
5
  SHA512:
6
- metadata.gz: 1d732cd15c2acf298a872ce6a51de97740e6edfa1a1fdad9cfa4372423e0a78cf51578e8057eaeef38afcc0f250db3acd6f4ada9bb02778e8c829815cb4fc894
7
- data.tar.gz: 7e38818c44bb7529e2c9283aaa975560acb6363f56fa221a8075013dd7a0731424659653a307dc9bb6edd844e4ad2e52bd214a3744cb53a7d84d7f9b8c1d3d20
6
+ metadata.gz: bdc7bc60c215ca1514262f9b9ff0cce49208590e9fc5597440698a68678c40be21bd740b3539504409f137d433affe2e88ba09df9166f72f3b84e1d4b7cb88bc
7
+ data.tar.gz: 889a05b473558941b51c3eb4c3ffdd07eb786aef86b2dc8043bb4d51813b9608079f5795285beba19362bec7dd9f830ef8b907e9d69774bfbb4364d8587a6bf2
data/lib/ruy.rb CHANGED
@@ -1,127 +1,7 @@
1
1
  require_relative 'ruy/rule'
2
- require_relative 'ruy/adapters'
2
+ require_relative 'ruy/rule_set'
3
3
  require_relative 'ruy/conditions'
4
- require_relative 'ruy/rule_storage'
4
+ require_relative 'ruy/context'
5
+ require_relative 'ruy/variable_context'
6
+ require_relative 'ruy/outcome'
5
7
  require_relative 'ruy/time_pattern'
6
-
7
- module Ruy
8
- class RuleSet < Rule
9
-
10
- attr_reader :name
11
- attr_reader :outcomes
12
- attr_accessor :metadata
13
-
14
- def initialize
15
- super
16
-
17
- @outcomes = []
18
- @fallback = nil
19
- @metadata = {}
20
- end
21
-
22
- def [](key)
23
- @metadata[key]
24
- end
25
-
26
- def []=(key, value)
27
- @metadata[key] = value
28
- end
29
-
30
- def call(ctx)
31
- var_ctx = VariableContext.new(ctx, @vars)
32
- if @apply = super(var_ctx)
33
- compute_outcome(var_ctx)
34
- else
35
- @fallback
36
- end
37
- end
38
-
39
- def apply?
40
- @apply
41
- end
42
-
43
- def compute_outcome(var_ctx)
44
- @outcomes.each do |outcome|
45
- result = outcome.call(var_ctx)
46
- unless result.nil?
47
- return result
48
- end
49
- end
50
-
51
- nil
52
- end
53
-
54
- def to_hash
55
- if @outcomes.any?
56
- super.merge({ outcomes: @outcomes.map { |o| o.to_hash } })
57
- end
58
- end
59
-
60
- def fallback(value)
61
- @fallback = value
62
- end
63
-
64
- def outcome(value, &block)
65
- outcome = Outcome.new(value)
66
- outcome.instance_exec(&block) if block_given?
67
- @outcomes << outcome
68
- end
69
-
70
- def method_missing(m, *args, &block)
71
- super
72
- end
73
- end
74
-
75
- class Context < Hash
76
- def self.from_hash(hash)
77
- ctx = Context.new
78
- ctx.merge!(hash)
79
-
80
- ctx
81
- end
82
- end
83
-
84
- class Outcome < Rule
85
- attr_reader :value
86
-
87
- def initialize(value)
88
- super()
89
-
90
- @value = value
91
- @params = [@value]
92
- end
93
-
94
- def call(ctx)
95
- @value if super(ctx)
96
- end
97
-
98
- def ==(o)
99
- o.kind_of?(Outcome) &&
100
- value == o.value &&
101
- conditions == o.conditions
102
- end
103
- end
104
-
105
- # Context that can resolve variable access
106
- class VariableContext
107
- def initialize(ctx, vars = {})
108
- @ctx = ctx
109
- @vars = vars
110
- @resolved_vars = {}
111
- end
112
-
113
- # Resolve the given attr from the variables or the context
114
- # If attribute can't be resolved then throw an exception
115
- #
116
- # @param [Symbol] attr
117
- # @return [Object]
118
- def resolve(attr)
119
- if @vars.include?(attr)
120
- @resolved_vars[attr] ||= @ctx.instance_exec(&@vars[attr])
121
- else
122
- @ctx.fetch(attr) { |key| @ctx[key.to_s] }
123
- end
124
- end
125
- end
126
-
127
- end
@@ -3,6 +3,7 @@ require_relative 'conditions/any'
3
3
  require_relative 'conditions/assert'
4
4
  require_relative 'conditions/between'
5
5
  require_relative 'conditions/cond'
6
+ require_relative 'conditions/day_of_week'
6
7
  require_relative 'conditions/eq'
7
8
  require_relative 'conditions/except'
8
9
  require_relative 'conditions/greater_than_or_equal'
@@ -11,7 +12,3 @@ require_relative 'conditions/included'
11
12
  require_relative 'conditions/less_than'
12
13
  require_relative 'conditions/less_than_or_equal'
13
14
  require_relative 'conditions/tz'
14
-
15
- module Ruy
16
- module Conditions; end
17
- end
@@ -7,9 +7,8 @@ module Ruy
7
7
 
8
8
  # @param attr Context attribute's name
9
9
  def initialize(attr)
10
- super()
10
+ super
11
11
  @attr = attr
12
- @params = [@attr]
13
12
  end
14
13
 
15
14
  def call(var_ctx)
@@ -12,14 +12,10 @@ module Ruy
12
12
  # @param to Range upper bound
13
13
  # @yield a block in the context of the current rule
14
14
  def initialize(attr, from, to, &block)
15
- super()
16
-
15
+ super
17
16
  @attr = attr
18
17
  @from = from
19
18
  @to = to
20
-
21
- @params = [@attr, @from, @to]
22
-
23
19
  instance_exec(&block) if block_given?
24
20
  end
25
21
 
@@ -0,0 +1,44 @@
1
+ require 'time'
2
+ require 'tzinfo'
3
+
4
+ module Ruy
5
+ module Conditions
6
+
7
+ # Expects that a Time object's date corresponds to a specified day of the week
8
+ class DayOfWeek < Ruy::Rule
9
+ DAYS_INTO_WEEK = %w(sunday monday tuesday wednesday thursday friday saturday)
10
+ attr_reader :attr, :value, :tz_identifier
11
+
12
+ # @param attr
13
+ # @param value
14
+ # @param tz_identifier
15
+ def initialize(attr, value, tz_identifier = 'UTC')
16
+ super
17
+ @attr = attr
18
+ @value = value
19
+ @tz_identifier = tz_identifier
20
+ @tz = TZInfo::Timezone.get(tz_identifier)
21
+ end
22
+
23
+ # @param [Ruy::VariableContext] var_ctx
24
+ def call(var_ctx)
25
+ resolved = var_ctx.resolve(@attr)
26
+ cmp = @tz.utc_to_local(resolved.to_time.utc)
27
+
28
+ if @value.is_a?(Fixnum)
29
+ cmp.wday == @value
30
+ else
31
+ DAYS_INTO_WEEK.include?(@value.to_s) && cmp.send("#{@value}?")
32
+ end
33
+ end
34
+
35
+ # @param o
36
+ def ==(o)
37
+ o.kind_of?(DayOfWeek) &&
38
+ attr == o.attr &&
39
+ value == o.value &&
40
+ tz_identifier == o.tz_identifier
41
+ end
42
+ end
43
+ end
44
+ end
@@ -9,11 +9,9 @@ module Ruy
9
9
  # @param attr Context attribute's name
10
10
  # @param value Expected value
11
11
  def initialize(attr, value)
12
- super()
13
-
12
+ super
14
13
  @attr = attr
15
14
  @value = value
16
- @params = [@attr, @value]
17
15
  end
18
16
 
19
17
  def call(var_ctx)
@@ -13,12 +13,9 @@ module Ruy
13
13
  # @param value Non-expected value
14
14
  # @yield a block in the context of the current rule
15
15
  def initialize(attr = nil, value = nil, &block)
16
- super()
17
-
16
+ super
18
17
  @attr = attr
19
18
  @value = value
20
- @params = [@attr, @value]
21
-
22
19
  instance_exec(&block) if block_given?
23
20
  end
24
21
 
@@ -9,13 +9,9 @@ module Ruy
9
9
  # @param value
10
10
  # @yield a block in the context of the current rule
11
11
  def initialize(attr, value, &block)
12
- super()
13
-
12
+ super
14
13
  @attr = attr
15
14
  @value = value
16
-
17
- @params = [@attr, @value]
18
-
19
15
  instance_exec(&block) if block_given?
20
16
  end
21
17
 
@@ -9,13 +9,9 @@ module Ruy
9
9
  # @param values Expected set of values
10
10
  # @yield a block in the context of the current rule
11
11
  def initialize(attr, values, &block)
12
- super()
13
-
12
+ super
14
13
  @attr = attr
15
14
  @values = values
16
-
17
- @params = [@attr, @values]
18
-
19
15
  instance_exec(&block) if block_given?
20
16
  end
21
17
 
@@ -9,13 +9,9 @@ module Ruy
9
9
  # @param value Expected set of values
10
10
  # @yield a block in the context of the current rule
11
11
  def initialize(attr, value, &block)
12
- super()
13
-
12
+ super
14
13
  @attr = attr
15
14
  @value = value
16
-
17
- @params = [@attr, @value]
18
-
19
15
  instance_exec(&block) if block_given?
20
16
  end
21
17
 
@@ -8,11 +8,9 @@ module Ruy
8
8
  # @param attr Context attribute's name
9
9
  # @param value
10
10
  def initialize(attr, value)
11
- super()
11
+ super
12
12
  @attr = attr
13
13
  @value = value
14
-
15
- @params = [@attr, @value]
16
14
  end
17
15
 
18
16
  def call(var_ctx)
@@ -8,11 +8,9 @@ module Ruy
8
8
  # @param attr Context attribute's name
9
9
  # @param value
10
10
  def initialize(attr, value)
11
- super()
11
+ super
12
12
  @attr = attr
13
13
  @value = value
14
-
15
- @params = [@attr, @value]
16
14
  end
17
15
 
18
16
  def call(var_ctx)
@@ -8,9 +8,8 @@ module Ruy
8
8
  class TZ < Ruy::Rule
9
9
  # @param [String] tz_identifier String representing IANA's time zone identifier.
10
10
  def initialize(tz_identifier)
11
- super()
11
+ super
12
12
  @tz_identifier = tz_identifier
13
- @params = [@tz_identifier]
14
13
  end
15
14
 
16
15
  # @param [Ruy::VariableContext] var_ctx
@@ -20,6 +19,13 @@ module Ruy
20
19
  end
21
20
  end
22
21
 
22
+ # Adds a DayOfWeek condition
23
+ #
24
+ # @param (see Ruy::Conditions::DayOfWeek#initialize)
25
+ def day_of_week(attr, dow)
26
+ @conditions << DayOfWeek.new(attr, dow, @tz_identifier)
27
+ end
28
+
23
29
  # Intercepts an 'eq' call to the superclass and enhances its arguments
24
30
  #
25
31
  # @param (see Ruy::Conditions::Eq#initialize)
@@ -0,0 +1,10 @@
1
+ module Ruy
2
+ class Context < Hash
3
+ def self.from_hash(hash)
4
+ ctx = Context.new
5
+ ctx.merge!(hash)
6
+
7
+ ctx
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Ruy
2
+ class Outcome < Rule
3
+ attr_reader :value
4
+
5
+ def initialize(value)
6
+ super
7
+ @value = value
8
+ end
9
+
10
+ def call(ctx)
11
+ if super(ctx)
12
+ @value
13
+ end
14
+ end
15
+
16
+ def ==(o)
17
+ o.kind_of?(Outcome) &&
18
+ value == o.value &&
19
+ conditions == o.conditions
20
+ end
21
+ end
22
+ end
data/lib/ruy/rule.rb CHANGED
@@ -1,63 +1,13 @@
1
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
2
  class Rule
18
-
19
3
  attr_reader :conditions
20
4
  attr_reader :vars
21
5
 
22
- def initialize
6
+ def initialize(*args)
23
7
  @conditions = []
24
8
  @vars = {}
25
9
  @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)
10
+ @params = args
61
11
  end
62
12
 
63
13
  # Adds an All condition.
@@ -155,7 +105,8 @@ module Ruy
155
105
 
156
106
  # Adds a TZ condition block
157
107
  #
158
- # @param [String] tz_identifier String representing IANA's time zone identifier. Defaults to UTC if none passed.
108
+ # @param [String] tz_identifier String representing IANA's
109
+ # time zone identifier. Defaults to UTC if none passed.
159
110
  # @yield Evaluates the given block in the context of the TZ rule
160
111
  def tz(tz_identifier = 'UTC', &block)
161
112
  cond = Conditions::TZ.new(tz_identifier)
@@ -183,7 +134,8 @@ module Ruy
183
134
 
184
135
  # Defines a variable.
185
136
  #
186
- # If both value and block are given, only the block will be taken into account.
137
+ # If both value and block are given,
138
+ # only the block will be taken into account.
187
139
  #
188
140
  # @param name The name of the variable
189
141
  # @param value The value of the variable
@@ -217,14 +169,6 @@ module Ruy
217
169
  vars.keys == o.vars.keys
218
170
  end
219
171
 
220
- private
221
-
222
- # Getter method for rules params. It returns all the params without nil objects
223
- #
224
- # @return [Array<Object>]
225
- def params
226
- @params.compact
227
- end
228
-
229
172
  end
173
+
230
174
  end
@@ -0,0 +1,61 @@
1
+ module Ruy
2
+ class RuleSet < Rule
3
+ attr_reader :outcomes
4
+ attr_accessor :metadata
5
+
6
+ def initialize
7
+ super
8
+ @outcomes = []
9
+ @fallback = nil
10
+ @metadata = {}
11
+ end
12
+
13
+ def outcome(value, &block)
14
+ outcome = Outcome.new(value)
15
+ outcome.instance_exec(&block) if block_given?
16
+ @outcomes << outcome
17
+ end
18
+
19
+ def fallback(value)
20
+ @fallback = value
21
+ end
22
+
23
+ def call(ctx)
24
+ var_ctx = VariableContext.new(ctx, @vars)
25
+ if @apply = super(var_ctx)
26
+ compute_outcome(var_ctx)
27
+ else
28
+ @fallback
29
+ end
30
+ end
31
+
32
+ def [](key)
33
+ @metadata[key]
34
+ end
35
+
36
+ def []=(key, value)
37
+ @metadata[key] = value
38
+ end
39
+
40
+ def apply?
41
+ @apply
42
+ end
43
+
44
+ def compute_outcome(var_ctx)
45
+ @outcomes.each do |outcome|
46
+ result = outcome.call(var_ctx)
47
+ unless result.nil?
48
+ return result
49
+ end
50
+ end
51
+
52
+ nil
53
+ end
54
+
55
+ def method_missing(m, *args, &block)
56
+ super
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -4,54 +4,114 @@ module Ruy
4
4
  class TimePattern
5
5
  include Comparable
6
6
 
7
- EXP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(z(\S+))?$/
7
+ WELL_FORMED_TS_EXP = /^(?<year>\d{4}|\*)-(?<month>\d{2}|\*)-(?<day>\d{2}|\*)T(?<hour>\d{2}|\*):(?<minute>\d{2}|\*):(?<second>\d{2}|\*)(z(?<time_zone>\S+))?$/
8
8
 
9
- attr_reader :tz, :local_time, :utc_time
9
+ attr_reader :year, :month, :day, :hour, :min, :sec, :time_zone, :tz, :local,
10
+ :utc, :utc_offset
10
11
 
11
- # @param [String] pattern String representing a Ruy's well-formed timestamp pattern
12
- # @param [String] tz_identifier String representing IANA's time zone identifier. Defaults to UTC if none passed.
12
+ # @param [String] pattern String representing a Ruy's
13
+ # well-formed timestamp pattern
14
+ # @param [String] tz_identifier String representing IANA's
15
+ # time zone identifier. Defaults to UTC if none passed.
13
16
  def initialize(pattern, tz_identifier = 'UTC')
14
- raise ArgumentError, 'Pattern is malformed' unless match_data = pattern.match(EXP)
17
+ unless match_data = pattern.match(WELL_FORMED_TS_EXP)
18
+ raise ArgumentError, "#{pattern.inspect} is malformed"
19
+ end
15
20
 
16
- year = match_data[1].to_i
17
- month = match_data[2].to_i
18
- day = match_data[3].to_i
19
- hours = match_data[4].to_i
20
- min = match_data[5].to_i
21
- sec = match_data[6].to_i
22
- tz_identifier = match_data[8] || tz_identifier
21
+ @pattern = pattern
22
+
23
+ @year = match_data[:year] == '*' ? nil : match_data[:year].to_i
24
+ @month = match_data[:month] == '*' ? nil : match_data[:month].to_i
25
+ @day = match_data[:day] == '*' ? nil : match_data[:day].to_i
26
+ @hour = match_data[:hour] == '*' ? nil : match_data[:hour].to_i
27
+ @min = match_data[:minute] == '*' ? nil : match_data[:minute].to_i
28
+ @sec = match_data[:second] == '*' ? nil : match_data[:second].to_i
29
+ @time_zone = match_data[:time_zone]
23
30
 
24
31
  # Store the TZInfo::Timezone object corresponding to the specified time zone
25
- @tz = TZInfo::Timezone.get(tz_identifier)
32
+ @tz = TZInfo::Timezone.get(@time_zone || tz_identifier)
26
33
 
27
34
  # Store a Time object with values based on the specified time zone
28
- @local_time = Time.new(year, month, day, hours, min, sec, '+00:00')
35
+ @local = Time.new(year || 0, month, day, hour, min, sec, '+00:00')
29
36
 
30
37
  # Store a Time object with values based on UTC
31
- @utc_time = @tz.local_to_utc(@local_time)
38
+ @utc = @tz.local_to_utc(@local)
39
+ @utc_offset = @tz.current_period.utc_total_offset
32
40
  end
33
41
 
34
- # Implements Ruby's spaceship operator to work with TimePattern objects.
42
+ # Implements Ruby's spaceship operator to work with Time objects.
43
+ # Uses Object's spaceship operator if passed object
44
+ # does not respond to #to_time.
35
45
  #
36
- # @param [TimePattern|Time]
46
+ # @param [#to_time]
37
47
  # @return [Fixnum]
38
- def <=>(time)
39
- @utc_time <=> (time.is_a?(self.class) ? time.utc_time : time)
48
+ def <=>(o)
49
+ if o.respond_to?(:to_time)
50
+ time = o.to_time
51
+ time_to_local = @tz.utc_to_local(time.utc)
52
+
53
+ self_time = Time.gm(
54
+ self.year || time_to_local.year,
55
+ self.month || time_to_local.month,
56
+ self.day || time_to_local.day,
57
+ self.hour || time_to_local.hour,
58
+ self.min || time_to_local.min,
59
+ self.sec || time_to_local.sec,
60
+ Rational(time_to_local.nsec, 1000)
61
+ )
62
+
63
+ @tz.local_to_utc(self_time) <=> time
64
+
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ # Overrides Object equal operator and uses Comparable equality
71
+ # for Time objects.
72
+ # Uses identity comparison if passed object does not respond to #to_time.
73
+ #
74
+ # @param [#to_time]
75
+ # @return [Boolean]
76
+ def ==(o)
77
+ if o.is_a?(self.class)
78
+ return year == o.year &&
79
+ month == o.month &&
80
+ day == o.day &&
81
+ hour == o.hour &&
82
+ min == o.min &&
83
+ sec == o.sec &&
84
+ time_zone == o.time_zone
85
+ elsif o.respond_to?(:to_time)
86
+ super
87
+ else
88
+ equal?(o)
89
+ end
40
90
  end
41
91
 
42
- # Returns a well-formed Ruy timestamp with IANA time zone identifier representing the current TimePattern object.
92
+ # Returns a well-formed Ruy timestamp with IANA time zone identifier
93
+ # representing the current TimePattern object.
43
94
  #
44
95
  # @return [String]
45
96
  def to_s
46
- @local_time.strftime("%Y-%m-%dT%H:%M:%Sz#{@tz.identifier}")
97
+ @pattern
98
+ end
99
+
100
+ # Returns a representation of the time pattern
101
+ #
102
+ # @return [String]
103
+ def inspect
104
+ @pattern
47
105
  end
48
106
 
49
- # Overrides Ruby's method missing call to redirect calls to the stored Time object in case it responds to the
50
- # missing method. Will call to super in case it doesn't.
107
+ # Overrides Ruby's method missing call to redirect calls
108
+ # to the stored Time object in case it responds to the missing method.
109
+ # Will call to super in case it doesn't.
51
110
  #
52
111
  # @param (see BasicObject#method_missing)
53
112
  def method_missing(method, *args)
54
- @utc_time.respond_to?(method) ? @utc_time.send(method, *args) : super
113
+ @utc.respond_to?(method) ? @utc.send(method, *args) : super
55
114
  end
115
+
56
116
  end
57
117
  end
@@ -0,0 +1,24 @@
1
+ module Ruy
2
+ # Context that can resolve variable access
3
+ class VariableContext
4
+ def initialize(ctx, vars)
5
+ @ctx = ctx
6
+ @vars = vars
7
+
8
+ @resolved_vars = {}
9
+ end
10
+
11
+ # Resolve the given attr from the variables or the context
12
+ # If attribute can't be resolved then throw an exception
13
+ #
14
+ # @param [Symbol] attr
15
+ # @return [Object]
16
+ def resolve(attr)
17
+ if @vars.include?(attr)
18
+ @resolved_vars[attr] ||= @ctx.instance_exec(&@vars[attr])
19
+ else
20
+ @ctx.fetch(attr) { |key| @ctx[key.to_s] }
21
+ end
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moove-IT
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.1'
41
- - !ruby/object:Gem::Dependency
42
- name: sequel
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '4.12'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '4.12'
55
41
  description:
56
42
  email:
57
43
  executables: []
@@ -59,15 +45,13 @@ extensions: []
59
45
  extra_rdoc_files: []
60
46
  files:
61
47
  - lib/ruy.rb
62
- - lib/ruy/adapters.rb
63
- - lib/ruy/adapters/file_adapter.rb
64
- - lib/ruy/adapters/sequel_adapter.rb
65
48
  - lib/ruy/conditions.rb
66
49
  - lib/ruy/conditions/all.rb
67
50
  - lib/ruy/conditions/any.rb
68
51
  - lib/ruy/conditions/assert.rb
69
52
  - lib/ruy/conditions/between.rb
70
53
  - lib/ruy/conditions/cond.rb
54
+ - lib/ruy/conditions/day_of_week.rb
71
55
  - lib/ruy/conditions/eq.rb
72
56
  - lib/ruy/conditions/except.rb
73
57
  - lib/ruy/conditions/greater_than_or_equal.rb
@@ -76,9 +60,12 @@ files:
76
60
  - lib/ruy/conditions/less_than.rb
77
61
  - lib/ruy/conditions/less_than_or_equal.rb
78
62
  - lib/ruy/conditions/tz.rb
63
+ - lib/ruy/context.rb
64
+ - lib/ruy/outcome.rb
79
65
  - lib/ruy/rule.rb
80
- - lib/ruy/rule_storage.rb
66
+ - lib/ruy/rule_set.rb
81
67
  - lib/ruy/time_pattern.rb
68
+ - lib/ruy/variable_context.rb
82
69
  homepage: https://github.com/Moove-it/ruy
83
70
  licenses:
84
71
  - MIT
data/lib/ruy/adapters.rb DELETED
@@ -1,6 +0,0 @@
1
- require_relative 'adapters/file_adapter'
2
- require_relative 'adapters/sequel_adapter'
3
-
4
- module Ruy
5
- module Adapters; end
6
- end
@@ -1,28 +0,0 @@
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
@@ -1,40 +0,0 @@
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
@@ -1,36 +0,0 @@
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