# frozen_string_literal: truemoduleAnthropicmoduleInternalmoduleType# @api privatemoduleConverter# rubocop:disable Lint/UnusedMethodArgument# @api private## @param value [Object]## @param state [Hash{Symbol=>Object}] .## @option state [Boolean, :strong] :strictness## @option state [Hash{Symbol=>Object}] :exactness## @option state [Integer] :branched## @return [Object]defcoerce(value,state:)=(raiseNotImplementedError)# @api private## @param value [Object]## @param state [Hash{Symbol=>Object}] .## @option state [Boolean] :can_retry## @return [Object]defdump(value,state:)casevalueinArrayvalue.map{Anthropic::Internal::Type::Unknown.dump(_1,state: state)}inHashvalue.transform_values{Anthropic::Internal::Type::Unknown.dump(_1,state: state)}inAnthropic::Internal::Type::BaseModelvalue.class.dump(value,state: state)inStringIOvalue.stringinPathname|IOstate[:can_retry]=falseifvalue.is_a?(IO)Anthropic::Internal::Util::SerializationAdapter.new(value)elsevalueendend# rubocop:enable Lint/UnusedMethodArgumentclass<<self# @api private## @param spec [Hash{Symbol=>Object}, Proc, Anthropic::Internal::Type::Converter, Class] .## @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const## @option spec [Proc] :enum## @option spec [Proc] :union## @option spec [Boolean] :"nil?"## @return [Proc]deftype_info(spec)casespecinProcspecinHashtype_info(spec.slice(:const,:enum,:union).first&.last)intrue|false->{Anthropic::Internal::Type::Boolean}inAnthropic::Internal::Type::Converter|Class|Symbol->{spec}inNilClass|Integer|Float->{spec.class}endend# @api private## Based on `target`, transform `value` into `target`, to the extent possible:## 1. if the given `value` conforms to `target` already, return the given `value`# 2. if it's possible and safe to convert the given `value` to `target`, then the# converted value# 3. otherwise, the given `value` unaltered## The coercion process is subject to improvement between minor release versions.# See https://docs.pydantic.dev/latest/concepts/unions/#smart-mode## @param target [Anthropic::Internal::Type::Converter, Class]## @param value [Object]## @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`, or `:strong`. This informs the# coercion strategy when we have to decide between multiple possible conversion# targets:## - `true`: the conversion must be exact, with minimum coercion.# - `false`: the conversion can be approximate, with some coercion.# - `:strong`: the conversion must be exact, with no coercion, and raise an error# if not possible.## The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For# any given conversion attempt, the exactness will be updated based on how closely# the value recursively matches the target type:## - `yes`: the value can be converted to the target type with minimum coercion.# - `maybe`: the value can be converted to the target type with some reasonable# coercion.# - `no`: the value cannot be converted to the target type.## See implementation below for more details.## @option state [Boolean, :strong] :strictness## @option state [Hash{Symbol=>Object}] :exactness## @option state [Integer] :branched## @return [Object]defcoerce(target,value,state: {strictness: true,exactness: {yes: 0,no: 0,maybe: 0},branched: 0})# rubocop:disable Lint/SuppressedException# rubocop:disable Metrics/BlockNestingstrictness,exactness=state.fetch_values(:strictness,:exactness)casetargetinAnthropic::Internal::Type::Converterreturntarget.coerce(value,state: state)inClassifvalue.is_a?(target)exactness[:yes]+=1returnvalueendcasetargetin->{_1<=NilClass}exactness[value.nil??:yes::maybe]+=1returnnilin->{_1<=Integer}ifvalue.is_a?(Integer)exactness[:yes]+=1returnvalueelsifstrictness==:strong&&Integer(value,exception: false)!=valuemessage="no implicit conversion of #{value.class} into #{target.inspect}"raisevalue.is_a?(Numeric)?ArgumentError.new(message):TypeError.new(message)elseKernel.thendoreturnInteger(value).tap{exactness[:maybe]+=1}rescueArgumentError,TypeErrorendendin->{_1<=Float}ifvalue.is_a?(Numeric)exactness[:yes]+=1returnFloat(value)elsifstrictness==:strongmessage="no implicit conversion of #{value.class} into #{target.inspect}"raiseTypeError.new(message)elseKernel.thendoreturnFloat(value).tap{exactness[:maybe]+=1}rescueArgumentError,TypeErrorendendin->{_1<=String}casevalueinString|Symbol|Numericexactness[value.is_a?(Numeric)?:maybe::yes]+=1returnvalue.to_sinStringIOexactness[:yes]+=1returnvalue.stringelseifstrictness==:strongmessage="no implicit conversion of #{value.class} into #{target.inspect}"raiseTypeError.new(message)endendin->{_1<=Date||_1<=Time}Kernel.thendoreturntarget.parse(value).tap{exactness[:yes]+=1}rescueArgumentError,TypeError=>eraiseeifstrictness==:strongendin->{_1<=StringIO}ifvalue.is_a?(String)exactness[:yes]+=1returnStringIO.new(value.b)elseendinSymbolcasevalueinSymbol|Stringifvalue.to_sym==targetexactness[:yes]+=1returntargetelseexactness[:maybe]+=1returnvalueendelseifstrictness==:strongmessage="cannot convert non-matching #{value.class} into #{target.inspect}"raiseArgumentError.new(message)endendelseendexactness[:no]+=1value# rubocop:enable Metrics/BlockNesting# rubocop:enable Lint/SuppressedExceptionend# @api private## @param target [Anthropic::Internal::Type::Converter, Class]## @param value [Object]## @param state [Hash{Symbol=>Object}] .## @option state [Boolean] :can_retry## @return [Object]defdump(target,value,state: {can_retry: true})casetargetinAnthropic::Internal::Type::Convertertarget.dump(value,state: state)elseAnthropic::Internal::Type::Unknown.dump(value,state: state)endendendendendendend