Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions lib/floe/workflow/choice_rule/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ class ChoiceRule
class Data < Floe::Workflow::ChoiceRule
TYPES = ["String", "Numeric", "Boolean", "Timestamp", "Present", "Null"].freeze
COMPARES = ["Equals", "LessThan", "GreaterThan", "LessThanEquals", "GreaterThanEquals", "Matches"].freeze
OPERATIONS = TYPES.each_with_object({}) { |dt, a| a[dt] = :"is_#{dt.downcase}?" }
.merge(COMPARES.each_with_object({}) { |op, a| a[op] = :"op_#{op.downcase}?" }).freeze
# e.g.: (Is)(String), (Is)(Present)
TYPE_CHECK = /^(Is)(#{TYPES.join("|")})$/
TYPE_CHECK = /^Is(#{TYPES.join("|")})$/
# e.g.: (String)(LessThan)(Path), (Numeric)(GreaterThanEquals)()
OPERATION = /^(#{(TYPES - %w[Null Present]).join("|")})(#{COMPARES.join("|")})(Path)?$/

attr_reader :variable, :compare_key, :operation, :type, :compare_predicate, :path
attr_reader :variable, :compare_key, :operator, :type, :compare_predicate, :path
Comment on lines -14 to +16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the "public" api - not a big deal if it's internal, but is anything else using this?

Copy link
Member Author

@kbrock kbrock Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've been pretty lax on public and private api for these models.

Every attribute here is internal to this class only.

In a separate PR, do we want to circle through and mark private/public?
Would it buy us anything, or will it just make debugging more difficult?

Come to think of it, I think only Workflow and Context have a public api.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's fine, I just wanted to make sure that was accounted for or not.


def initialize(_workflow, _name, payload)
super
Expand All @@ -25,7 +27,7 @@ def true?(context, input)

lhs = variable_value(context, input)
rhs = compare_value(context, input)
send(operation, lhs, rhs)
send(OPERATIONS[operator], lhs, rhs)
end

private
Expand Down Expand Up @@ -110,22 +112,20 @@ def parse_compare_key
# e.g. (String)(GreaterThan)(Path)
if (match_values = OPERATION.match(key))
@compare_key = key
@type, operator, @path = match_values.captures
@operation = :"op_#{operator.downcase}?"
@type, @operator, @path = match_values.captures
@compare_predicate = parse_predicate(type)
break
# e.g. (Is)(String)
elsif (match_value = TYPE_CHECK.match(key))
@compare_key = key
_operator, type = match_value.captures
@operator = match_value.captures.first
# type: nil means no runtime type checking.
@type = @path = nil
@operation = :"is_#{type.downcase}?"
@compare_predicate = parse_predicate("Boolean")
break
end
end
parser_error!("requires a compare key") if compare_key.nil? || operation.nil?
parser_error!("requires a compare key") if compare_key.nil? || operator.nil?
end

# parse predicate at initialization time
Expand Down Expand Up @@ -180,7 +180,7 @@ def fetch_path(field_name, field_path, context, input)
# if we have runtime checking, check against that type
# otherwise assume checking a TYPE_CHECK predicate and check against Boolean
def correct_type?(value, data_type)
send(:"is_#{data_type.downcase}?", value)
send(OPERATIONS[data_type], value)
end
end
end
Expand Down