demarches-normaliennes/app/models/logic.rb

135 lines
3.5 KiB
Ruby
Raw Normal View History

2022-06-09 11:48:30 +02:00
module Logic
def self.from_h(h)
2022-07-05 14:47:32 +02:00
class_from_name(h['term']).from_h(h)
2022-06-09 11:48:30 +02:00
end
def self.from_json(s)
from_h(JSON.parse(s))
end
def self.class_from_name(name)
[
ChampValue,
Constant,
Empty,
LessThan,
LessThanEq,
Eq,
NotEq,
GreaterThanEq,
GreaterThan,
EmptyOperator,
IncludeOperator,
ExcludeOperator,
And,
Or,
InDepartementOperator,
NotInDepartementOperator,
InRegionOperator,
NotInRegionOperator
].find { |c| c.name == name }
2022-06-09 11:48:30 +02:00
end
2022-09-26 21:22:43 +02:00
def self.ensure_compatibility_from_left(condition, type_de_champs)
2022-06-09 13:45:56 +02:00
left = condition.left
right = condition.right
operator_class = condition.class
2022-09-26 21:07:43 +02:00
case [left.type(type_de_champs), condition]
2022-06-09 13:45:56 +02:00
in [:boolean, _]
operator_class = Eq
in [:empty, _]
operator_class = EmptyOperator
in [:enum, _]
operator_class = Eq
in [:commune_enum, _] | [:epci_enum, _]
operator_class = InDepartementOperator
in [:departement_enum, _]
operator_class = Eq
in [:enums, _]
operator_class = IncludeOperator
2022-06-09 13:45:56 +02:00
in [:number, EmptyOperator]
operator_class = Eq
in [:number, _]
end
2022-09-26 21:20:32 +02:00
if !compatible_type?(left, right, type_de_champs)
2022-09-26 21:07:43 +02:00
right = case left.type(type_de_champs)
2022-06-09 13:45:56 +02:00
when :boolean
Constant.new(true)
when :empty
Empty.new
when :enum, :enums, :commune_enum, :epci_enum, :departement_enum
2022-09-26 21:19:00 +02:00
Constant.new(left.options(type_de_champs).first.second)
2022-06-09 13:45:56 +02:00
when :number
Constant.new(0)
end
end
operator_class.new(left, right)
end
2022-09-26 21:20:32 +02:00
def self.compatible_type?(left, right, type_de_champs)
2022-09-26 21:07:43 +02:00
case [left.type(type_de_champs), right.type(type_de_champs)]
2022-06-09 13:43:35 +02:00
in [a, ^a] # syntax for same type
true
in [:enum, :string] | [:enums, :string] | [:commune_enum, :string] | [:epci_enum, :string] | [:departement_enum, :string]
true
2022-06-09 13:43:35 +02:00
else
false
end
end
2022-07-01 17:42:44 +02:00
def self.add_empty_condition_to(condition)
empty_condition = EmptyOperator.new(Empty.new, Empty.new)
if condition.nil?
empty_condition
elsif [And, Or].include?(condition.class)
condition.tap { |c| c.operands << empty_condition }
else
Logic::And.new([condition, empty_condition])
end
end
2022-07-04 12:23:46 +02:00
def self.split_condition(condition)
[condition.left, condition.class.name, condition.right]
end
2022-06-09 12:14:08 +02:00
def ds_eq(left, right) = Logic::Eq.new(left, right)
2022-08-09 15:41:42 +02:00
def ds_not_eq(left, right) = Logic::NotEq.new(left, right)
2022-06-09 12:14:08 +02:00
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 ds_include(left, right) = Logic::IncludeOperator.new(left, right)
def ds_in_departement(left, right) = Logic::InDepartementOperator.new(left, right)
def ds_not_in_departement(left, right) = Logic::NotInDepartementOperator.new(left, right)
def ds_in_region(left, right) = Logic::InRegionOperator.new(left, right)
def ds_not_in_region(left, right) = Logic::NotInRegionOperator.new(left, right)
def ds_exclude(left, right) = Logic::ExcludeOperator.new(left, right)
2022-06-09 11:48:30 +02:00
def constant(value) = Logic::Constant.new(value)
2022-06-16 17:21:47 +02:00
def champ_value(stable_id) = Logic::ChampValue.new(stable_id)
2022-06-09 11:54:29 +02:00
def empty = Logic::Empty.new
2022-06-09 12:14:08 +02:00
def empty_operator(left, right) = Logic::EmptyOperator.new(left, right)
2022-06-09 14:00:18 +02:00
def ds_or(operands) = Logic::Or.new(operands)
def ds_and(operands) = Logic::And.new(operands)
2022-06-09 11:48:30 +02:00
end