in lib/anthropic/internal/type/base_model.rb [182:296]
def ==(other) = self.class == other.class && @data == other.to_h
class << self
def coerce(value, state:)
exactness = state.fetch(:exactness)
if value.is_a?(self.class)
exactness[:yes] += 1
return value
end
unless (val = Anthropic::Internal::Util.coerce_hash(value)).is_a?(Hash)
exactness[:no] += 1
return value
end
exactness[:yes] += 1
keys = val.keys.to_set
instance = new
data = instance.to_h
fields.each do |name, field|
mode, required, target = field.fetch_values(:mode, :required, :type)
api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
unless val.key?(api_name)
if required && mode != :dump && const == Anthropic::Internal::OMIT
exactness[nilable ? :maybe : :no] += 1
else
exactness[:yes] += 1
end
next
end
item = val.fetch(api_name)
keys.delete(api_name)
converted =
if item.nil? && (nilable || !required)
exactness[nilable ? :yes : :maybe] += 1
nil
else
coerced = Anthropic::Internal::Type::Converter.coerce(target, item, state: state)
case target
in Anthropic::Internal::Type::Converter | Symbol
coerced
else
item
end
end
data.store(name, converted)
end
keys.each { data.store(_1, val.fetch(_1)) }
instance
end
def dump(value, state:)
unless (coerced = Anthropic::Internal::Util.coerce_hash(value)).is_a?(Hash)
return super
end
acc = {}
coerced.each do |key, val|
name = key.is_a?(String) ? key.to_sym : key
case (field = known_fields[name])
in nil
acc.store(name, super(val, state: state))
else
api_name, mode, type_fn = field.fetch_values(:api_name, :mode, :type_fn)
case mode
in :coerce
next
else
target = type_fn.call
acc.store(api_name, Anthropic::Internal::Type::Converter.dump(target, val, state: state))
end
end
end
known_fields.each_value do |field|
api_name, mode, const = field.fetch_values(:api_name, :mode, :const)
next if mode == :coerce || acc.key?(api_name) || const == Anthropic::Internal::OMIT
acc.store(api_name, const)
end
acc
end
end