Skip to content

Commit

Permalink
Introduce unary data choice rules
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrock committed May 23, 2024
1 parent c95f621 commit 8adf634
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 36 deletions.
6 changes: 6 additions & 0 deletions lib/floe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
require_relative "floe/workflow/choice_rule/not"
require_relative "floe/workflow/choice_rule/or"
require_relative "floe/workflow/choice_rule/and"
require_relative "floe/workflow/choice_rule/is_boolean"
require_relative "floe/workflow/choice_rule/is_null"
require_relative "floe/workflow/choice_rule/is_numeric"
require_relative "floe/workflow/choice_rule/is_present"
require_relative "floe/workflow/choice_rule/is_string"
require_relative "floe/workflow/choice_rule/is_timestamp"
require_relative "floe/workflow/choice_rule/data"
require_relative "floe/workflow/context"
require_relative "floe/workflow/path"
Expand Down
2 changes: 1 addition & 1 deletion lib/floe/workflow/choice_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def build(payload)
elsif (sub_payloads = payload["Or"])
Floe::Workflow::ChoiceRule::Or.new(payload, build_children(sub_payloads))
else
Floe::Workflow::ChoiceRule::Data.new(payload)
Floe::Workflow::ChoiceRule::Data.build(payload)
end
end

Expand Down
53 changes: 18 additions & 35 deletions lib/floe/workflow/choice_rule/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,26 @@ class Workflow
class ChoiceRule
class Data < Floe::Workflow::ChoiceRule
COMPARE_KEYS = %w[IsNull IsPresent IsNumeric IsString IsBoolean IsTimestamp String Numeric Boolean Timestamp].freeze
DATA_RULES = {
"IsNull" => Floe::Workflow::ChoiceRule::IsNull,
"IsPresent" => Floe::Workflow::ChoiceRule::IsPresent,
"IsNumeric" => Floe::Workflow::ChoiceRule::IsNumeric,
"IsString" => Floe::Workflow::ChoiceRule::IsString,
"IsBoolean" => Floe::Workflow::ChoiceRule::IsBoolean,
"IsTimestamp" => Floe::Workflow::ChoiceRule::IsTimestamp,
}

attr_reader :compare_key
attr_accessor :ref, :ref_path

def self.build(payload)
compare_key = payload.keys.detect { |key| key.match?(/^(#{DATA_RULES.keys.join("|")})/) }
if compare_key
DATA_RULES[compare_key].new(payload)
else
Floe::Workflow::ChoiceRule::Data.new(payload)
end
end

def initialize(*)
super
Expand All @@ -26,12 +44,6 @@ def true?(context, input)
return false unless valid?(lhs)

case compare_key
when "IsNull" then is_null?(lhs)
when "IsPresent" then is_present?(lhs)
when "IsNumeric" then is_numeric?(lhs)
when "IsString" then is_string?(lhs)
when "IsBoolean" then is_boolean?(lhs)
when "IsTimestamp" then is_timestamp?(lhs)
when "StringEquals", "StringEqualsPath",
"NumericEquals", "NumericEqualsPath",
"BooleanEquals", "BooleanEqualsPath",
Expand Down Expand Up @@ -63,38 +75,9 @@ def true?(context, input)
private

def valid?(value)
!value.nil? || %w[IsNull IsPresent].include?(compare_key)
end

def is_null?(value) # rubocop:disable Naming/PredicateName
value.nil?
end

def is_present?(value) # rubocop:disable Naming/PredicateName
!value.nil?
end

def is_numeric?(value) # rubocop:disable Naming/PredicateName
value.kind_of?(Integer) || value.kind_of?(Float)
end

def is_string?(value) # rubocop:disable Naming/PredicateName
value.kind_of?(String)
end

def is_boolean?(value) # rubocop:disable Naming/PredicateName
[true, false].include?(value)
end

def is_timestamp?(value) # rubocop:disable Naming/PredicateName
require "date"

DateTime.rfc3339(value)
true
rescue TypeError, Date::Error
false
end

def compare_value(context, input)
@ref_path ? Path.value(@ref_path, context, input) : @ref
end
Expand Down
13 changes: 13 additions & 0 deletions lib/floe/workflow/choice_rule/is_boolean.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsBoolean < Floe::Workflow::ChoiceRule
def true?(context, input)
[true, false].include?(variable_value(context, input))
end
end
end
end
end
13 changes: 13 additions & 0 deletions lib/floe/workflow/choice_rule/is_null.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsNull < Floe::Workflow::ChoiceRule
def true?(context, input)
variable_value(context, input).nil?
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/floe/workflow/choice_rule/is_numeric.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsNumeric < Floe::Workflow::ChoiceRule
def true?(context, input)
value = variable_value(context, input)
value.kind_of?(Integer) || value.kind_of?(Float)
end
end
end
end
end
13 changes: 13 additions & 0 deletions lib/floe/workflow/choice_rule/is_present.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsPresent < IsNull
def true?(context, input)
!variable_value(context, input).nil?
end
end
end
end
end
13 changes: 13 additions & 0 deletions lib/floe/workflow/choice_rule/is_string.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsString < Floe::Workflow::ChoiceRule
def true?(context, input)
variable_value(context, input).kind_of?(String)
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/floe/workflow/choice_rule/is_timestamp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Floe
class Workflow
class ChoiceRule
class IsTimestamp < Floe::Workflow::ChoiceRule
def true?(context, input)
value = variable_value(context, input)
require "date"

DateTime.rfc3339(value)
true
rescue TypeError, Date::Error
false
end
end
end
end
end

0 comments on commit 8adf634

Please sign in to comment.