# frozen_string_literal: true module Logic def self.from_h(h) class_from_name(h['term']).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, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, ExcludeOperator, And, Or, InDepartementOperator, NotInDepartementOperator, InRegionOperator, NotInRegionOperator ].find { |c| c.name == name } end def self.ensure_compatibility_from_left(condition, type_de_champs) left = condition.left right = condition.right operator_class = condition.class case [left.type(type_de_champs), condition] 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 in [:number, EmptyOperator] operator_class = Eq in [:number, _] end if !compatible_type?(left, right, type_de_champs) right = case left.type(type_de_champs) when :boolean Constant.new(true) when :empty Empty.new when :enum, :enums, :commune_enum, :epci_enum, :departement_enum Constant.new(left.options(type_de_champs).first.second) when :number Constant.new(0) end end operator_class.new(left, right) end def self.compatible_type?(left, right, type_de_champs) case [left.type(type_de_champs), right.type(type_de_champs)] in [a, ^a] # syntax for same type true in [:enum, :string] | [:enums, :string] | [:commune_enum, :string] | [:epci_enum, :string] | [:departement_enum, :string] true else false end end 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 def self.split_condition(condition) [condition.left, condition.class.name, condition.right] end def ds_eq(left, right) = Logic::Eq.new(left, right) def ds_not_eq(left, right) = Logic::NotEq.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 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) 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