class EntitySchema::Contracts::Contract
Check data with strict contract, described with Hash-based DSL
Attributes
rules[R]
Public Class Methods
build(*arguments_arr)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 8 def build(*arguments_arr) params = arguments_arr.to_a options = params.last.is_a?(Hash) ? params.pop : {} new(to_params_hash(params).merge(options)) end
new(rules)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 21 def initialize(rules) @rules = rules.dup @rules.each_value { |rule| rule.transform_values! { |v| v.nil? ? [nil] : Array(v) } } @rules.each(&:freeze).freeze freeze end
to_params_hash(arr)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 14 def to_params_hash(arr) arr.each_with_object({}).with_index do |(value, params), i| params["argument #{i + 1}"] = value end end
Public Instance Methods
+(other)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 28 def +(other) args = other.to_a options = args.last.is_a?(Hash) ? args.pop : {} other_rules = to_params_hash(args).merge(options) merge(rules.merge(other_rules)) end
call(*params, skip_unknown: false, **options)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 40 def call(*params, skip_unknown: false, **options) # rubocop:disable Metrics/AbcSize keyvalue = to_params_hash(params).merge(options) keyvalue.each do |key, value| rules.key?(key) || skip_unknown || raise_unknown!(key, value) r = rules[key] next if r[:eq]&.any? { |expectation| expectation == value } next if r[:type]&.any? { |type| value.is_a?(type) } next if r[:respond_to]&.any? { |meth| value.respond_to?(meth) } raise_unexpected_value(r, key, value) end true end
merge(other)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 35 def merge(other) other_rules = other.to_h self.class.new(rules.merge(other_rules)) end
to_a()
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 58 def to_a params, options = to_arguments(rules) params << options end
to_h()
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 54 def to_h rules end
Private Instance Methods
raise_unexpected_value(rules, key, value)
click to toggle source
rubocop:disable Metrics/LineLength
# File lib/entity_schema/contracts/contract.rb, line 86 def raise_unexpected_value(rules, key, value) msg = "Unexpected #{key.inspect} value `#{value.inspect}`. \n" \ ' Expected to:' msgs = [] msgs << "\n be equal to: #{rules[:eq]}" if rules.key?(:eq) msgs << "\n be one of: #{rules[:type]}" if rules[:type] msgs << "\n respond to one of the methods: #{rules[:respond_to]}" if rules.key?(:respond_to) raise TypeError, (msg + msgs * ' OR') end
raise_unknown!(key, value)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 80 def raise_unknown!(key, value) raise "Unknown option `#{key.inspect} => #{value.inspect}` given." \ " Known options: #{rules.keys}" end
to_arguments(hash)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 71 def to_arguments(hash) arr = [] hash = hash.dup hash.each_key do |k| arr << hash.delete(k) if k.is_a?(String) && k.start_with?('argument ') end [arr, hash] end
to_params_hash(a)
click to toggle source
# File lib/entity_schema/contracts/contract.rb, line 67 def to_params_hash(a) self.class.to_params_hash(a) end