diff options
author | Parker Selbert <parker@sorentwo.com> | 2021-12-05 12:50:22 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-05 19:50:22 +0100 |
commit | 1f0422ac2ede9b13aee6e6b1674616e140b2945e (patch) | |
tree | 1c557aa421c7a80988cf26eaed4ea869e5f13b26 | |
parent | 5b1b85be84b44dd9a949aeaba1f86805a69bb7c0 (diff) | |
download | elixir-1f0422ac2ede9b13aee6e6b1674616e140b2945e.tar.gz |
Specific base typespecs (#11449)
* Use specific options for base option typespecs
Each function had `keyword` as the option type, which didn't help guard
against typos or mismatched options.
* Fix padding use in encode/decode identity test
-rw-r--r-- | lib/elixir/lib/base.ex | 33 | ||||
-rw-r--r-- | lib/elixir/test/elixir/base_test.exs | 15 |
2 files changed, 31 insertions, 17 deletions
diff --git a/lib/elixir/lib/base.ex b/lib/elixir/lib/base.ex index 2eb2265d4..c902963b6 100644 --- a/lib/elixir/lib/base.ex +++ b/lib/elixir/lib/base.ex @@ -92,6 +92,9 @@ defmodule Base do """ + @type encode_case :: :upper | :lower + @type decode_case :: :upper | :lower | :mixed + b16_alphabet = '0123456789ABCDEF' b64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' b64url_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' @@ -267,7 +270,7 @@ defmodule Base do "666f6f626172" """ - @spec encode16(binary, keyword) :: binary + @spec encode16(binary, case: encode_case) :: binary def encode16(data, opts \\ []) when is_binary(data) do case = Keyword.get(opts, :case, :upper) do_encode16(case, data) @@ -300,7 +303,7 @@ defmodule Base do {:ok, "foobar"} """ - @spec decode16(binary, keyword) :: {:ok, binary} | :error + @spec decode16(binary, case: decode_case) :: {:ok, binary} | :error def decode16(string, opts \\ []) do {:ok, decode16!(string, opts)} rescue @@ -337,7 +340,7 @@ defmodule Base do "foobar" """ - @spec decode16!(binary, keyword) :: binary + @spec decode16!(binary, case: encode_case) :: binary def decode16!(string, opts \\ []) def decode16!(string, opts) when is_binary(string) and rem(byte_size(string), 2) == 0 do @@ -367,7 +370,7 @@ defmodule Base do "Zm9vYg" """ - @spec encode64(binary, keyword) :: binary + @spec encode64(binary, padding: boolean) :: binary def encode64(data, opts \\ []) when is_binary(data) do pad? = Keyword.get(opts, :padding, true) do_encode64(data, pad?) @@ -397,7 +400,7 @@ defmodule Base do {:ok, "foob"} """ - @spec decode64(binary, keyword) :: {:ok, binary} | :error + @spec decode64(binary, ignore: :whitespace, padding: boolean) :: {:ok, binary} | :error def decode64(string, opts \\ []) when is_binary(string) do {:ok, decode64!(string, opts)} rescue @@ -431,7 +434,7 @@ defmodule Base do "foob" """ - @spec decode64!(binary, keyword) :: binary + @spec decode64!(binary, ignore: :whitespace, padding: boolean) :: binary def decode64!(string, opts \\ []) when is_binary(string) do pad? = Keyword.get(opts, :padding, true) string |> remove_ignored(opts[:ignore]) |> do_decode64(pad?) @@ -453,7 +456,7 @@ defmodule Base do "_3_-_A" """ - @spec url_encode64(binary, keyword) :: binary + @spec url_encode64(binary, padding: boolean) :: binary def url_encode64(data, opts \\ []) when is_binary(data) do pad? = Keyword.get(opts, :padding, true) do_encode64url(data, pad?) @@ -481,7 +484,7 @@ defmodule Base do {:ok, <<255, 127, 254, 252>>} """ - @spec url_decode64(binary, keyword) :: {:ok, binary} | :error + @spec url_decode64(binary, ignore: :whitespace, padding: boolean) :: {:ok, binary} | :error def url_decode64(string, opts \\ []) when is_binary(string) do {:ok, url_decode64!(string, opts)} rescue @@ -513,7 +516,7 @@ defmodule Base do <<255, 127, 254, 252>> """ - @spec url_decode64!(binary, keyword) :: binary + @spec url_decode64!(binary, ignore: :whitespace, padding: boolean) :: binary def url_decode64!(string, opts \\ []) when is_binary(string) do pad? = Keyword.get(opts, :padding, true) string |> remove_ignored(opts[:ignore]) |> do_decode64url(pad?) @@ -551,7 +554,7 @@ defmodule Base do "MZXW6YTBOI" """ - @spec encode32(binary, keyword) :: binary + @spec encode32(binary, case: encode_case, padding: boolean) :: binary def encode32(data, opts \\ []) when is_binary(data) do case = Keyword.get(opts, :case, :upper) pad? = Keyword.get(opts, :padding, true) @@ -594,7 +597,7 @@ defmodule Base do {:ok, "foobar"} """ - @spec decode32(binary, keyword) :: {:ok, binary} | :error + @spec decode32(binary, case: decode_case, padding: boolean) :: {:ok, binary} | :error def decode32(string, opts \\ []) do {:ok, decode32!(string, opts)} rescue @@ -640,7 +643,7 @@ defmodule Base do "foobar" """ - @spec decode32!(binary, keyword) :: binary + @spec decode32!(binary, case: decode_case, padding: boolean) :: binary def decode32!(string, opts \\ []) when is_binary(string) do case = Keyword.get(opts, :case, :upper) pad? = Keyword.get(opts, :padding, true) @@ -680,7 +683,7 @@ defmodule Base do "CPNMUOJ1E8" """ - @spec hex_encode32(binary, keyword) :: binary + @spec hex_encode32(binary, case: encode_case, padding: boolean) :: binary def hex_encode32(data, opts \\ []) when is_binary(data) do case = Keyword.get(opts, :case, :upper) pad? = Keyword.get(opts, :padding, true) @@ -724,7 +727,7 @@ defmodule Base do {:ok, "foobar"} """ - @spec hex_decode32(binary, keyword) :: {:ok, binary} | :error + @spec hex_decode32(binary, case: decode_case, padding: boolean) :: {:ok, binary} | :error def hex_decode32(string, opts \\ []) do {:ok, hex_decode32!(string, opts)} rescue @@ -771,7 +774,7 @@ defmodule Base do "foobar" """ - @spec hex_decode32!(binary, keyword) :: binary + @spec hex_decode32!(binary, case: decode_case, padding: boolean) :: binary def hex_decode32!(string, opts \\ []) when is_binary(string) do case = Keyword.get(opts, :case, :upper) pad? = Keyword.get(opts, :padding, true) diff --git a/lib/elixir/test/elixir/base_test.exs b/lib/elixir/test/elixir/base_test.exs index 78cc6b5ad..028a47abe 100644 --- a/lib/elixir/test/elixir/base_test.exs +++ b/lib/elixir/test/elixir/base_test.exs @@ -799,10 +799,21 @@ defmodule BaseTest do |> Enum.shuffle() |> IO.iodata_to_binary() + allowed_opts = + encode + |> Function.info() + |> Keyword.fetch!(:name) + |> case do + :encode16 -> [:case] + :encode64 -> [:padding] + :url_encode64 -> [:padding] + _ -> [:case, :padding] + end + expected = data - |> encode.(case: encode_case, pad: pad?) - |> decode.(case: decode_case, pad: pad?) + |> encode.(Keyword.take([case: encode_case, padding: pad?], allowed_opts)) + |> decode.(Keyword.take([case: decode_case, padding: pad?], allowed_opts)) assert data == expected, "identity did not match for #{inspect(data)} when #{inspect(encode)} (#{encode_case})" |