Skip to content

Instantly share code, notes, and snippets.

@joeyates
Created October 3, 2015 08:59
Show Gist options
  • Save joeyates/acf8ea5dcdccd293c1d0 to your computer and use it in GitHub Desktop.
Save joeyates/acf8ea5dcdccd293c1d0 to your computer and use it in GitHub Desktop.
Do object-scoped from encoding of HTTP parameters
defmodule FormEncode do
def form_encode(params) when is_map(params) do
form_encode([], params)
end
def form_encode(nesting, value) when is_map(value) do
Enum.map_join(value, "&", fn({k, v}) ->
n1 = Enum.reverse(Enum.reverse(nesting), [k])
form_encode(n1, v)
end)
end
def form_encode(nesting, value) when is_binary(value) do
URI.encode_www_form(form_key(nesting) <> "=" <> value)
end
def form_key([h | []]) do
to_string(h)
end
def form_key([h | t]) do
to_string(h) <> "[" <> Enum.map_join(t, "][", &(to_string(&1))) <> "]"
end
end
defmodule FormEncodeTest do
use ExUnit.Case
import FormEncode
test ".form_encode with a flat map, string keys, one pair" do
assert form_encode(%{"hello" => "ciao"}) == "hello%3Dciao"
end
test ".form_encode with a flat map, atom keys, one pair" do
assert form_encode(%{hello: "ciao"}) == "hello%3Dciao"
end
test ".form_encode with a singly nested maps, string keys, one pair" do
assert form_encode(%{"greetings" => %{"hello" => "ciao"}}) == "greetings%5Bhello%5D%3Dciao"
end
test ".form_encode with a singly nested maps, atom keys, one pair" do
assert form_encode(%{greetings: %{hello: "ciao"}}) == "greetings%5Bhello%5D%3Dciao"
end
test ".form_encode with a deeply nested maps, string keys, multiple final pairs" do
expected = "translations%5Bgreetings%5D%5Bbuon+giorno%5D%3Dgood+day&translations%5Bgreetings%5D%5Bhello%5D%3Dciao"
result = form_encode(%{"translations" => %{"greetings" => %{"hello" => "ciao", "buon giorno" => "good day"}}})
assert result == expected
end
test ".form_encode with a deeply nested maps, string keys, multiple non-final pairs" do
expected = "translations%5Bgreetings%5D%5Bhello%5D%3Dciao&translations%5Bnumbers%5D%5Bone%5D%3Duno"
result = form_encode(%{"translations" => %{"numbers" => %{"one" => "uno"}, "greetings" => %{"hello" => "ciao"}}})
assert result == expected
end
test ".form_key for a single-item string list is the value" do
assert form_key(["ciao"]) == "ciao"
end
test ".form_key for a single-item atom list is the value as a string" do
assert form_key([:ciao]) == "ciao"
end
test ".form_key wraps non-initial values in square brackets" do
assert form_key(["ciao", "hello", "hi"]) == "ciao[hello][hi]"
end
test ".form_key wraps non-initial values in square brackets, mixed values" do
assert form_key(["ciao", :hello, "hi"]) == "ciao[hello][hi]"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment