lib/httpx/transcoder.rb in httpx-0.16.1 vs lib/httpx/transcoder.rb in httpx-0.17.0
- old
+ new
@@ -2,11 +2,15 @@
module HTTPX
module Transcoder
extend Registry
- def self.normalize_keys(key, value, cond = nil, &block)
+ using RegexpExtensions unless Regexp.method_defined?(:match?)
+
+ module_function
+
+ def normalize_keys(key, value, cond = nil, &block)
if (cond && cond.call(value))
block.call(key.to_s, value)
elsif value.respond_to?(:to_ary)
if value.empty?
block.call("#{key}[]")
@@ -20,9 +24,66 @@
normalize_keys("#{key}[#{child_key}]", child_value, cond, &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 /\[\]/.match?(key)
+
+ 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"