From 810771a1c550ba765baef6ee0b7065a67f32e749 Mon Sep 17 00:00:00 2001 From: Syphax Bouazzouni Date: Tue, 28 Feb 2023 06:24:26 +0100 Subject: [PATCH] implement symmetric validator --- lib/goo/validators/enforce.rb | 2 + .../validators/implementations/existence.rb | 5 ++- .../validators/implementations/symmetric.rb | 44 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 lib/goo/validators/implementations/symmetric.rb diff --git a/lib/goo/validators/enforce.rb b/lib/goo/validators/enforce.rb index 9283c070..70953645 100644 --- a/lib/goo/validators/enforce.rb +++ b/lib/goo/validators/enforce.rb @@ -39,6 +39,8 @@ def enforce(inst,attr,value) check Goo::Validators::DataType, inst, attr, value, opt, DateTime when :float, Float check Goo::Validators::DataType, inst, attr, value, opt, Float + when :symmetric + check Goo::Validators::Symmetric, inst, attr, value, opt when Proc call_proc(opt, inst, attr) when /^max_/, /^min_/ diff --git a/lib/goo/validators/implementations/existence.rb b/lib/goo/validators/implementations/existence.rb index a551f35d..6e759154 100644 --- a/lib/goo/validators/implementations/existence.rb +++ b/lib/goo/validators/implementations/existence.rb @@ -8,9 +8,12 @@ class Existence < ValidatorBase error_message ->(obj) { "`#{@value}` value cannot be nil"} validity_check -> (obj) do - not (@value.nil? || self.class.empty?(@value) || self.class.empty_array?(@value)) + not self.class.empty_value?(@value) end + def self.empty_value?(value) + value.nil? || self.empty?(value) || self.empty_array?(value) + end def self.empty?(value) empty_string?(value) || empty_to_s?(value) end diff --git a/lib/goo/validators/implementations/symmetric.rb b/lib/goo/validators/implementations/symmetric.rb new file mode 100644 index 00000000..c1c9055c --- /dev/null +++ b/lib/goo/validators/implementations/symmetric.rb @@ -0,0 +1,44 @@ +module Goo + module Validators + class Symmetric < ValidatorBase + include Validator + + key :symmetric + + error_message ->(obj) { + "symmetric error" + } + + validity_check -> (obj) do + return true if Existence.empty_value?(@value) + + return Array(@value).select{|x| not self.class.symmetric?(@attr,x, @inst)}.empty? + end + + def self.symmetric?(attr, value, source_object) + if self.respond_to?(attr, value) + target_values = self.attr_value(attr, value) + return target_values.any?{ |target_object| self.equivalent?(target_object, source_object)} + end + + return false + end + + def self.respond_to?(attr, object) + object && object.respond_to?(attr) + end + + def self.attr_value(attr, object) + Array(object.send(attr)) + end + + def self.equivalent?(object1, object2) + if object1.respond_to?(:id) && object2.respond_to?(:id) + object1.id.eql?(object2.id) + else + object2 == object1 + end + end + end + end +end \ No newline at end of file