Add any unpacking. Filter blind maps.
This commit is contained in:
parent
2712046a9d
commit
68ed3ba1d9
@ -21,10 +21,15 @@ module VagrantPlugins
|
||||
# available to all mapper calls
|
||||
def initialize(*args)
|
||||
@known_arguments = args
|
||||
Mapper.generate_anys
|
||||
@mappers = Mapper.registered.map(&:new)
|
||||
@identifiers = []
|
||||
end
|
||||
|
||||
def clone
|
||||
n = self.class.new(*known_arguments)
|
||||
end
|
||||
|
||||
# Add an argument to be included with mapping calls
|
||||
#
|
||||
# @param v [Object] Argument value
|
||||
@ -55,6 +60,13 @@ module VagrantPlugins
|
||||
thing.object_id.to_s
|
||||
end
|
||||
|
||||
def unany(any)
|
||||
type = any.type.split('/').last.to_s.split('.').inject(Object) { |memo, name|
|
||||
memo.const_get(name.to_s.capitalize)
|
||||
}
|
||||
any.unpack(type)
|
||||
end
|
||||
|
||||
# Map a given value
|
||||
#
|
||||
# @param value [Object] Value to map
|
||||
@ -74,16 +86,37 @@ module VagrantPlugins
|
||||
return val if val
|
||||
end
|
||||
|
||||
if value.is_a?(Google::Protobuf::Any)
|
||||
value = unany(value)
|
||||
end
|
||||
|
||||
args = ([value] + extra_args + known_arguments).compact
|
||||
result = nil
|
||||
|
||||
# For funcspec values, we want to pre-filter since they use
|
||||
# a custom validator. This will prevent invalid paths.
|
||||
if value.is_a?(SDK::FuncSpec::Value)
|
||||
map_mapper = self.clone
|
||||
valid_mappers = map_mapper.mappers.map do |m|
|
||||
next if !m.inputs.first.valid?(SDK::FuncSpec::Value) &&
|
||||
m.output.ancestors.include?(Google::Protobuf::MessageExts)
|
||||
next m if !m.inputs.first.valid?(SDK::FuncSpec::Value) ||
|
||||
m.inputs.first.valid?(value)
|
||||
logger.warn("removing mapper - invalid funcspec match - #{m}")
|
||||
nil
|
||||
end.compact
|
||||
map_mapper.mappers.replace(valid_mappers)
|
||||
else
|
||||
map_mapper = self
|
||||
end
|
||||
|
||||
# If we don't have a desired final type, test for mappers
|
||||
# that are satisfied by the arguments we have and run that
|
||||
# directly
|
||||
if to.nil?
|
||||
valid_outputs = []
|
||||
cb = lambda do |k|
|
||||
matches = mappers.find_all do |m|
|
||||
matches = map_mapper.mappers.find_all do |m|
|
||||
m.inputs.first.valid?(k)
|
||||
end
|
||||
outs = matches.map(&:output)
|
||||
@ -98,20 +131,21 @@ module VagrantPlugins
|
||||
|
||||
if valid_outputs.empty?
|
||||
raise TypeError,
|
||||
"No valid mappers found for input type `#{value.class}'"
|
||||
"No valid mappers found for input type `#{value.class}' (#{value})"
|
||||
end
|
||||
|
||||
valid_outputs.reverse!
|
||||
logger.debug("mapper output types discovered for input type `#{value.class}': #{valid_outputs}")
|
||||
logger.debug("mapper output types discovered for input type `#{value.class}': #{valid_outputs}, mappers:\n" + map_mapper.mappers.map(&:to_s).join("\n"))
|
||||
last_error = nil
|
||||
valid_outputs.each do |out|
|
||||
begin
|
||||
m_graph = Internal::Graph::Mappers.new(
|
||||
output_type: out,
|
||||
mappers: self,
|
||||
mappers: map_mapper,
|
||||
input_values: args,
|
||||
)
|
||||
result = m_graph.execute
|
||||
break
|
||||
rescue => err
|
||||
logger.debug("typeless mapping failure (non-critical): #{err} (input - #{value} / output #{out})")
|
||||
last_error = err
|
||||
@ -121,12 +155,13 @@ module VagrantPlugins
|
||||
else
|
||||
m_graph = Internal::Graph::Mappers.new(
|
||||
output_type: to,
|
||||
mappers: self,
|
||||
mappers: map_mapper,
|
||||
input_values: args,
|
||||
)
|
||||
result = m_graph.execute
|
||||
end
|
||||
cacher[cache_key] = result if cacher
|
||||
logger.debug("map of #{value} to #{to.inspect} => #{result}")
|
||||
result
|
||||
end
|
||||
|
||||
@ -140,10 +175,15 @@ module VagrantPlugins
|
||||
# actual values
|
||||
#
|
||||
# @param spec [SDK::FuncSpec::Spec]
|
||||
# @param expect [Array<Class>] Expected types for each argument
|
||||
# @return [Array<Object>, Object]
|
||||
def funcspec_map(spec, *extra_args)
|
||||
result = spec.args.map do |arg|
|
||||
map(arg, *extra_args)
|
||||
def funcspec_map(spec, *extra_args, expect: [])
|
||||
expect = Array(expect)
|
||||
expect.unshift(expect.pop).compact
|
||||
result = Array.new.tap do |result_args|
|
||||
spec.args.each_with_index do |arg, i|
|
||||
result_args << map(arg, *extra_args + result_args, to: expect[i])
|
||||
end
|
||||
end
|
||||
if result.size == 1
|
||||
return result.first
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user