diff --git a/lib/goo/validators/enforce.rb b/lib/goo/validators/enforce.rb index 70953645..bc0fd4c1 100644 --- a/lib/goo/validators/enforce.rb +++ b/lib/goo/validators/enforce.rb @@ -41,6 +41,8 @@ def enforce(inst,attr,value) check Goo::Validators::DataType, inst, attr, value, opt, Float when :symmetric check Goo::Validators::Symmetric, inst, attr, value, opt + when /^distinct_of_/ + check Goo::Validators::DistinctOf, inst, attr, value, opt, opt when Proc call_proc(opt, inst, attr) when /^max_/, /^min_/ diff --git a/lib/goo/validators/implementations/distinct_of.rb b/lib/goo/validators/implementations/distinct_of.rb new file mode 100644 index 00000000..820f5125 --- /dev/null +++ b/lib/goo/validators/implementations/distinct_of.rb @@ -0,0 +1,36 @@ +module Goo + module Validators + class DistinctOf < ValidatorBase + include Validator + + key :distinct_of_ + + error_message ->(obj) { "`#{@attr}` must be distinct of `#{@property}`"} + + validity_check -> (obj) do + return true if self.class.empty_value?(@value) + + self.distinct?(@inst, @property, @value) + end + + def initialize(inst, attr, value, key) + super(inst, attr, value) + @property = property(key) + end + + def property(opt) + opt[self.class.ids.size..opt.length].to_sym + end + + def distinct?(inst, property, value) + target_values = self.class.attr_value(property, inst) + current_values = Array(value) + + !current_values.any?{ |x| self.find_any?(target_values, x)} + end + def find_any?(array, value) + array.any?{ |x| self.class.equivalent_value?(value, x)} + end + end + end +end \ No newline at end of file