Module: DecisionAgent::Dsl::Operators::StringOperators

Defined in:
lib/decision_agent/dsl/operators/string_operators.rb

Overview

Handles string operators: contains, starts_with, ends_with, matches

Class Method Summary collapse

Class Method Details

.get_cached_regex(pattern, regex_cache: nil, regex_cache_mutex: nil) ⇒ Object

Get or compile regex with caching



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/decision_agent/dsl/operators/string_operators.rb', line 48

def self.get_cached_regex(pattern, regex_cache: nil, regex_cache_mutex: nil)
  return pattern if pattern.is_a?(Regexp)

  # Use provided caches or access ConditionEvaluator class variables
  cache = regex_cache
  mutex = regex_cache_mutex

  if cache.nil? || mutex.nil?
    cache = ConditionEvaluator.instance_variable_get(:@regex_cache)
    mutex = ConditionEvaluator.instance_variable_get(:@regex_cache_mutex)
  end

  # Fast path: check cache without lock
  cached = cache[pattern]
  return cached if cached

  # Slow path: compile and cache
  mutex.synchronize do
    cache[pattern] ||= Regexp.new(pattern.to_s)
  end
end

.handle(op, actual_value, expected_value, regex_cache: nil, regex_cache_mutex: nil) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/decision_agent/dsl/operators/string_operators.rb', line 8

def self.handle(op, actual_value, expected_value, regex_cache: nil, regex_cache_mutex: nil)
  case op
  when "contains"
    # Checks if string contains substring (case-sensitive)
    string_operator?(actual_value, expected_value) &&
      actual_value.include?(expected_value)

  when "starts_with"
    # Checks if string starts with prefix (case-sensitive)
    string_operator?(actual_value, expected_value) &&
      actual_value.start_with?(expected_value)

  when "ends_with"
    # Checks if string ends with suffix (case-sensitive)
    string_operator?(actual_value, expected_value) &&
      actual_value.end_with?(expected_value)

  when "matches"
    # Matches string against regular expression
    # expected_value can be a string (converted to regex) or Regexp object
    if !actual_value.is_a?(String) || expected_value.nil?
      false
    else
      begin
        regex = get_cached_regex(expected_value, regex_cache: regex_cache, regex_cache_mutex: regex_cache_mutex)
        !regex.match(actual_value).nil?
      rescue RegexpError
        false
      end
    end
  end
  # Returns nil if not handled by this module
end

.string_operator?(actual_value, expected_value) ⇒ Boolean

String operator validation

Returns:

  • (Boolean)


43
44
45
# File 'lib/decision_agent/dsl/operators/string_operators.rb', line 43

def self.string_operator?(actual_value, expected_value)
  actual_value.is_a?(String) && expected_value.is_a?(String)
end