Skip to content

Commit

Permalink
Refactor collection_coercer_for
Browse files Browse the repository at this point in the history
Refactor Grape::Validations::Types cache_key
  • Loading branch information
ericproulx committed Dec 19, 2024
1 parent bda6e59 commit 881fc9c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 21 deletions.
23 changes: 8 additions & 15 deletions lib/grape/validations/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,34 +176,27 @@ def create_coercer_instance(type, method, strict)
# CustomTypeCoercer (above) already handles such types when an explicit coercion
# method is supplied.
elsif Types.collection_of_custom?(type)
Types::CustomTypeCollectionCoercer.new(
Types.map_special(type.first), type.is_a?(Set)
)
Types::CustomTypeCollectionCoercer.new(Types.map_special(type.first), type.is_a?(Set))
else
DryTypeCoercer.coercer_instance_for(type, strict)
end
end

def cache_instance(type, method, strict, &_block)
key = cache_key(type, method, strict)

return @__cache[key] if @__cache.key?(key)

instance = yield

@__cache_write_lock.synchronize do
@__cache[key] = instance
yield.tap do |instance|
@__cache_write_lock.synchronize do
@__cache[key] = instance
end
end

instance
end

def cache_key(type, method, strict)
[type, method, strict].each_with_object(+'_') do |val, memo|
next if val.nil?

memo << '_' << val.to_s
end
key = [type.to_s, strict]
key.insert(1, method) if method
key.join('_')
end

instance_variable_set(:@__cache, {})
Expand Down
16 changes: 10 additions & 6 deletions lib/grape/validations/types/dry_type_coercer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@ class << self
# collection_coercer_for(Array)
# #=> Grape::Validations::Types::ArrayCoercer
def collection_coercer_for(type)
Grape::Validations::Types.const_get(:"#{type.name.camelize}Coercer")
case type
when Array
ArrayCoercer
when Set
SetCoercer
else
raise ArgumentError, "Unknown type: #{type}"
end
end

# Returns an instance of a coercer for a given type
def coercer_instance_for(type, strict = false)
return PrimitiveCoercer.new(type, strict) if type.instance_of?(Class)

# in case of a collection (Array[Integer]) the type is an instance of a collection,
# so we need to figure out the actual type
collection_coercer_for(type.class).new(type, strict)
klass = type.instance_of?(Class) ? PrimitiveCoercer : collection_coercer_for(type)
klass.new(type, strict)
end
end

Expand Down

0 comments on commit 881fc9c

Please sign in to comment.