Module: LaunchDarkly::Impl::EvaluatorOperators Private

Defined in:
lib/ldclient-rb/impl/evaluator_operators.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Defines the behavior of all operators that can be used in feature flag rules and segment rules.

Since:

  • 5.5.0

Class Method Summary collapse

Class Method Details

.add_zero_version_component(v) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



124
125
126
127
128
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 124

def self.add_zero_version_component(v)
  NUMERIC_VERSION_COMPONENTS_REGEX.match(v) { |m|
    m[0] + ".0" + v[m[0].length..-1]
  }
end

.apply(op, context_value, clause_value) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Applies an operator to produce a boolean result.

Parameters:

  • op (Symbol)

    one of the supported LaunchDarkly operators, as a symbol

  • context_value

    the value of the context attribute that is referenced in the current clause (left-hand side of the expression)

  • clause_value

    the constant value that context_value is being compared to (right-hand side of the expression)

Returns:

  • (Boolean)

    true if the expression should be considered a match; false if it is not a match, or if the values cannot be compared because they are of the wrong types, or if the operator is unknown

Since:

  • 5.5.0



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 18

def self.apply(op, context_value, clause_value)
  case op
  when :in
    context_value == clause_value
  when :startsWith
    string_op(context_value, clause_value, lambda { |a, b| a.start_with? b })
  when :endsWith
    string_op(context_value, clause_value, lambda { |a, b| a.end_with? b })
  when :contains
    string_op(context_value, clause_value, lambda { |a, b| a.include? b })
  when :matches
    string_op(context_value, clause_value, lambda { |a, b|
      begin
        re = Regexp.new b
        !re.match(a).nil?
      rescue
        false
      end
    })
  when :lessThan
    numeric_op(context_value, clause_value, lambda { |a, b| a < b })
  when :lessThanOrEqual
    numeric_op(context_value, clause_value, lambda { |a, b| a <= b })
  when :greaterThan
    numeric_op(context_value, clause_value, lambda { |a, b| a > b })
  when :greaterThanOrEqual
    numeric_op(context_value, clause_value, lambda { |a, b| a >= b })
  when :before
    date_op(context_value, clause_value, lambda { |a, b| a < b })
  when :after
    date_op(context_value, clause_value, lambda { |a, b| a > b })
  when :semVerEqual
    semver_op(context_value, clause_value, lambda { |a, b| a == b })
  when :semVerLessThan
    semver_op(context_value, clause_value, lambda { |a, b| a < b })
  when :semVerGreaterThan
    semver_op(context_value, clause_value, lambda { |a, b| a > b })
  when :segmentMatch
    # We should never reach this; it can't be evaluated based on just two parameters, because it requires
    # looking up the segment from the data store. Instead, we special-case this operator in clause_match_context.
    false
  else
    false
  end
end

.date_op(context_value, clause_value, fn) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



77
78
79
80
81
82
83
84
85
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 77

def self.date_op(context_value, clause_value, fn)
  ud = to_date(context_value)
  if !ud.nil?
    cd = to_date(clause_value)
    !cd.nil? && fn.call(ud, cd)
  else
    false
  end
end

.numeric_op(context_value, clause_value, fn) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



73
74
75
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 73

def self.numeric_op(context_value, clause_value, fn)
  (context_value.is_a? Numeric) && (clause_value.is_a? Numeric) && fn.call(context_value, clause_value)
end

.semver_op(context_value, clause_value, fn) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



87
88
89
90
91
92
93
94
95
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 87

def self.semver_op(context_value, clause_value, fn)
  uv = to_semver(context_value)
  if !uv.nil?
    cv = to_semver(clause_value)
    !cv.nil? && fn.call(uv, cv)
  else
    false
  end
end

.string_op(context_value, clause_value, fn) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



69
70
71
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 69

def self.string_op(context_value, clause_value, fn)
  (context_value.is_a? String) && (clause_value.is_a? String) && fn.call(context_value, clause_value)
end

.to_date(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 97

def self.to_date(value)
  if value.is_a? String
    begin
      DateTime.rfc3339(value).strftime("%Q").to_i
    rescue => e
      nil
    end
  elsif value.is_a? Numeric
    value
  else
    nil
  end
end

.to_semver(value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 5.5.0



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ldclient-rb/impl/evaluator_operators.rb', line 111

def self.to_semver(value)
  if value.is_a? String
    for _ in 0..2 do
      begin
        return Semantic::Version.new(value)
      rescue ArgumentError
        value = add_zero_version_component(value)
      end
    end
  end
  nil
end