Class: Smplkit::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/smplkit/flags/types.rb

Overview

Fluent builder for flag targeting rules.

Smplkit::Rule.new("Enable for enterprise users", environment: "staging")
  .when("user.plan", Smplkit::Op::EQ, "enterprise")
  .serve(true)

Multiple .when calls are AND’d. environment: is required so the target environment is unambiguous when the rule is passed to Flag#add_rule. .serve finalizes the rule and returns the built Hash ready to pass to add_rule.

Instance Method Summary collapse

Constructor Details

#initialize(description, environment:) ⇒ Rule

Returns a new instance of Rule.



180
181
182
183
184
# File 'lib/smplkit/flags/types.rb', line 180

def initialize(description, environment:)
  @description = description
  @environment = environment
  @conditions = []
end

Instance Method Details

#serve(value) ⇒ Object

Finalize the rule with value served on match and return the built Hash.



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/smplkit/flags/types.rb', line 217

def serve(value)
  logic =
    case @conditions.length
    when 0 then {}
    when 1 then @conditions[0]
    else { "and" => @conditions }
    end

  {
    "description" => @description,
    "logic" => logic,
    "value" => value,
    "environment" => @environment
  }
end

#when(*args) ⇒ Object

Add a condition. Multiple calls are AND’d at the top level.

Two forms:

- +when(var, op, value)+ - convenience for simple comparisons.
  +op+ accepts an +Op+ constant (preferred) or a raw string
  (e.g. +"=="+, +"contains"+).
- +when(expr)+ - escape hatch accepting an arbitrary JSON Logic
  expression (use this for OR, nested AND/OR, +if+, etc.).
  See https://jsonlogic.com/ for the full expression grammar.

Raises:

  • (ArgumentError)


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/smplkit/flags/types.rb', line 195

def when(*args)
  if args.length == 1 && args[0].is_a?(Hash)
    @conditions << args[0]
    return self
  end

  if args.length == 3
    var, op, value = args
    op_str = op.to_s
    @conditions << if op_str == "contains"
                     { "in" => [value, { "var" => var }] }
                   else
                     { op_str => [{ "var" => var }, value] }
                   end
    return self
  end

  raise ArgumentError,
        "Rule#when takes either (var, op, value) or a single JSON Logic Hash; got args=#{args.inspect}"
end