def extract_mapping(pattern, processor=nil)
reserved = Addressable::URI::CharacterClasses::RESERVED
unreserved = Addressable::URI::CharacterClasses::UNRESERVED
anything = reserved + unreserved
operator_expansion =
/\{-([a-zA-Z]+)\|([#{anything}]+)\|([#{anything}]+)\}/
variable_expansion = /\{([#{anything}]+?)(=([#{anything}]+))?\}/
expansions, expansion_regexp =
parse_template_pattern(pattern, processor)
unparsed_values = self.to_s.scan(expansion_regexp).flatten
mapping = {}
if self.to_s == pattern
return mapping
elsif expansions.size > 0 && expansions.size == unparsed_values.size
expansions.each_with_index do |expansion, index|
unparsed_value = unparsed_values[index]
if expansion =~ operator_expansion
operator, argument, variables =
parse_template_expansion(expansion)
extract_method = "extract_#{operator}_operator"
if ([extract_method, extract_method.to_sym] &
private_methods).empty?
raise InvalidTemplateOperatorError,
"Invalid template operator: #{operator}"
else
begin
send(
extract_method.to_sym, unparsed_value, processor,
argument, variables, mapping
)
rescue TemplateOperatorAbortedError
return nil
end
end
else
name = expansion[variable_expansion, 1]
value = unparsed_value
if processor != nil && processor.respond_to?(:restore)
value = processor.restore(name, value)
end
mapping[name] = value
end
end
return mapping
else
return nil
end
end