moduleDrymoduleTypesclassHash<Definition# The built-in Hash type has constructors that you can use to define# hashes with explicit schemas and coercible values using the built-in types.## Basic {Schema} evaluates default values for keys missing in input hash# (see {Schema#resolve_missing_value})## @see Dry::Types::Default#evaluate# @see Dry::Types::Default::Callable#evaluateclassSchema<Hash# @return [Hash{Symbol => Definition}]attr_reader:member_types# @param [Class] _primitive# @param [Hash] options# @option options [Hash{Symbol => Definition}] :member_typesdefinitialize(_primitive,options)@member_types=options.fetch(:member_types)superend# @param [Hash] hash# @return [Hash{Symbol => Object}]defcall(hash)coerce(hash)endalias_method:[],:call# @param [Hash] hash# @param [#call,nil] block# @yieldparam [Failure] failure# @yieldreturn [Result]# @return [Logic::Result]# @return [Object] if coercion fails and a block is givendeftry(hash,&block)success=trueoutput={}beginresult=try_coerce(hash)do|key,member_result|success&&=member_result.success?output[key]=member_result.inputmember_resultendrescueConstraintError,UnknownKeysError,SchemaError=>esuccess=falseresult=eendifsuccesssuccess(output)elsefailure=failure(output,result)block?yield(failure):failureendendprivate# @param [Hash] hash# @return [Hash{Symbol => Object}]deftry_coerce(hash)resolve(hash)do|type,key,value|yield(key,type.try(value))endend# @param [Hash] hash# @return [Hash{Symbol => Object}]defcoerce(hash)resolve(hash)do|type,key,value|begintype.call(value)rescueConstraintErrorraiseSchemaError.new(key,value)endendend# @param [Hash] hash# @return [Hash{Symbol => Object}]defresolve(hash)result={}member_types.eachdo|key,type|ifhash.key?(key)result[key]=yield(type,key,hash[key])elseresolve_missing_value(result,key,type)endendresultend# @param [Hash] result# @param [Symbol] key# @param [Type] type# @return [Object]# @see Dry::Types::Default#evaluate# @see Dry::Types::Default::Callable#evaluatedefresolve_missing_value(result,key,type)iftype.default?result[key]=type.evaluateelsesuperendendend# Permissive schema raises a {MissingKeyError} if the given key is missing# in provided hash.classPermissive<Schemaprivate# @param [Symbol] key# @raise [MissingKeyError] when key is missing in given inputdefresolve_missing_value(_,key,_)raiseMissingKeyError,keyendend# Strict hash will raise errors when keys are missing or value types are incorrect.# Strict schema raises a {UnknownKeysError} if there are any unexpected# keys in given hash, and raises a {MissingKeyError} if any key is missing# in it.# @example# hash = Types::Hash.strict(name: Types::String, age: Types::Coercible::Int)# hash[email: 'jane@doe.org', name: 'Jane', age: 21]# # => Dry::Types::SchemaKeyError: :email is missing in Hash inputclassStrict<Permissiveprivate# @param [Hash] hash# @return [Hash{Symbol => Object}]# @raise [UnknownKeysError]# if there any unexpected key in given hash# @raise [MissingKeyError]# if a required key is not present# @raise [SchemaError]# if a value is the wrong typedefresolve(hash)unexpected=hash.keys-member_types.keysraiseUnknownKeysError.new(*unexpected)unlessunexpected.empty?superdo|member_type,key,value|type=member_type.default??member_type.type:member_typeyield(type,key,value)endendend# {StrictWithDefaults} checks that there are no extra keys# (raises {UnknownKeysError} otherwise) and there a no missing keys# without default values given (raises {MissingKeyError} otherwise).# @see Default#evaluate# @see Default::Callable#evaluateclassStrictWithDefaults<Strictprivate# @param [Hash] result# @param [Symbol] key# @param [Type] type# @return [Object]# @see Dry::Types::Default#evaluate# @see Dry::Types::Default::Callable#evaluatedefresolve_missing_value(result,key,type)iftype.default?result[key]=type.evaluateelsesuperendendend# Weak schema provides safe types for every type given in schema hash# @see SafeclassWeak<Schema# @param [Class] primitive# @param [Hash] options# @see #initializedefself.new(primitive,options)member_types=options.fetch(:member_types).each_with_object({}){|(k,t),res|res[k]=t.safe}super(primitive,options.merge(member_types: member_types))end# @param [Object] value# @param [#call, nil] block# @yieldparam [Failure] failure# @yieldreturn [Result]# @return [Object] if block given# @return [Result,Logic::Result] otherwisedeftry(value,&block)ifvalue.is_a?(::Hash)superelseresult=failure(value,"#{value} must be a hash")block?yield(result):resultendendend# {Symbolized} hash will turn string key names into symbols.classSymbolized<Weakprivatedefresolve(hash)result={}member_types.eachdo|key,type|keyname=ifhash.key?(key)keyelsifhash.key?(string_key=key.to_s)string_keyendifkeynameresult[key]=yield(type,key,hash[keyname])elseresolve_missing_value(result,key,type)endendresultendendprivate_constant(*constants(false))endendend