demarches-normaliennes/app/models/logic.rb
2022-06-17 14:53:27 +02:00

84 lines
2 KiB
Ruby

module Logic
def self.from_h(h)
class_from_name(h['op']).from_h(h)
end
def self.from_json(s)
from_h(JSON.parse(s))
end
def self.class_from_name(name)
[ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, GreaterThanEq, GreaterThan, EmptyOperator, And, Or]
.find { |c| c.name == name }
end
def self.ensure_compatibility_from_left(condition)
left = condition.left
right = condition.right
operator_class = condition.class
case [left.type, condition]
in [:boolean, _]
operator_class = Eq
in [:empty, _]
operator_class = EmptyOperator
in [:enum, _]
operator_class = Eq
in [:number, EmptyOperator]
operator_class = Eq
in [:number, _]
in [:string, _]
operator_class = Eq
end
if !compatible_type?(left, right)
right = case left.type
when :boolean
Constant.new(true)
when :empty
Empty.new
when :enum
Constant.new(left.options.first)
when :number
Constant.new(0)
when :string
Constant.new('')
end
end
operator_class.new(left, right)
end
def self.compatible_type?(left, right)
case [left.type, right.type]
in [a, ^a] # syntax for same type
true
in [:enum, :string]
left.options.include?(right.value)
else
false
end
end
def ds_eq(left, right) = Logic::Eq.new(left, right)
def greater_than(left, right) = Logic::GreaterThan.new(left, right)
def greater_than_eq(left, right) = Logic::GreaterThanEq.new(left, right)
def less_than(left, right) = Logic::LessThan.new(left, right)
def less_than_eq(left, right) = Logic::LessThanEq.new(left, right)
def constant(value) = Logic::Constant.new(value)
def champ_value(stable_id) = Logic::ChampValue.new(stable_id)
def empty = Logic::Empty.new
def empty_operator(left, right) = Logic::EmptyOperator.new(left, right)
def ds_or(operands) = Logic::Or.new(operands)
def ds_and(operands) = Logic::And.new(operands)
end