1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
# frozen_string_literal: true
module HTTPX
module Transcoder
module_function
def normalize_keys(key, value, transcoder = self, &block)
if value.respond_to?(:to_ary)
if value.empty?
block.call("#{key}[]")
else
value.to_ary.each do |element|
transcoder.normalize_keys("#{key}[]", element, transcoder, &block)
end
end
elsif value.respond_to?(:to_hash)
value.to_hash.each do |child_key, child_value|
transcoder.normalize_keys("#{key}[#{child_key}]", child_value, transcoder, &block)
end
else
block.call(key.to_s, value)
end
end
# based on https://github.com/rack/rack/blob/d15dd728440710cfc35ed155d66a98dc2c07ae42/lib/rack/query_parser.rb#L82
def normalize_query(params, name, v, depth)
raise Error, "params depth surpasses what's supported" if depth <= 0
name =~ /\A[\[\]]*([^\[\]]+)\]*/
k = Regexp.last_match(1) || ""
after = Regexp.last_match ? Regexp.last_match.post_match : ""
if k.empty?
return Array(v) if !v.empty? && name == "[]"
return
end
case after
when ""
params[k] = v
when "["
params[name] = v
when "[]"
params[k] ||= []
raise Error, "expected Array (got #{params[k].class}) for param '#{k}'" unless params[k].is_a?(Array)
params[k] << v
when /^\[\]\[([^\[\]]+)\]$/, /^\[\](.+)$/
child_key = Regexp.last_match(1)
params[k] ||= []
raise Error, "expected Array (got #{params[k].class}) for param '#{k}'" unless params[k].is_a?(Array)
if params[k].last.is_a?(Hash) && !params_hash_has_key?(params[k].last, child_key)
normalize_query(params[k].last, child_key, v, depth - 1)
else
params[k] << normalize_query({}, child_key, v, depth - 1)
end
else
params[k] ||= {}
raise Error, "expected Hash (got #{params[k].class}) for param '#{k}'" unless params[k].is_a?(Hash)
params[k] = normalize_query(params[k], after, v, depth - 1)
end
params
end
def params_hash_has_key?(hash, key)
return false if key.include?("[]")
key.split(/[\[\]]+/).inject(hash) do |h, part|
next h if part == ""
return false unless h.is_a?(Hash) && h.key?(part)
h[part]
end
true
end
end
end
require "httpx/transcoder/body"
require "httpx/transcoder/form"
require "httpx/transcoder/json"
require "httpx/transcoder/chunker"
require "httpx/transcoder/deflate"
require "httpx/transcoder/gzip"
|