Skip to content

Commit cbba61a

Browse files
sorentwojosevalim
authored andcommitted
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
1 parent ebb347a commit cbba61a

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

lib/elixir/lib/base.ex

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ defmodule Base do
9292
9393
"""
9494

95+
@type encode_case :: :upper | :lower
96+
@type decode_case :: :upper | :lower | :mixed
97+
9598
b16_alphabet = '0123456789ABCDEF'
9699
b64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
97100
b64url_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
@@ -267,7 +270,7 @@ defmodule Base do
267270
"666f6f626172"
268271
269272
"""
270-
@spec encode16(binary, keyword) :: binary
273+
@spec encode16(binary, case: encode_case) :: binary
271274
def encode16(data, opts \\ []) when is_binary(data) do
272275
case = Keyword.get(opts, :case, :upper)
273276
do_encode16(case, data)
@@ -300,7 +303,7 @@ defmodule Base do
300303
{:ok, "foobar"}
301304
302305
"""
303-
@spec decode16(binary, keyword) :: {:ok, binary} | :error
306+
@spec decode16(binary, case: decode_case) :: {:ok, binary} | :error
304307
def decode16(string, opts \\ []) do
305308
{:ok, decode16!(string, opts)}
306309
rescue
@@ -337,7 +340,7 @@ defmodule Base do
337340
"foobar"
338341
339342
"""
340-
@spec decode16!(binary, keyword) :: binary
343+
@spec decode16!(binary, case: encode_case) :: binary
341344
def decode16!(string, opts \\ [])
342345

343346
def decode16!(string, opts) when is_binary(string) and rem(byte_size(string), 2) == 0 do
@@ -367,7 +370,7 @@ defmodule Base do
367370
"Zm9vYg"
368371
369372
"""
370-
@spec encode64(binary, keyword) :: binary
373+
@spec encode64(binary, padding: boolean) :: binary
371374
def encode64(data, opts \\ []) when is_binary(data) do
372375
pad? = Keyword.get(opts, :padding, true)
373376
do_encode64(data, pad?)
@@ -397,7 +400,7 @@ defmodule Base do
397400
{:ok, "foob"}
398401
399402
"""
400-
@spec decode64(binary, keyword) :: {:ok, binary} | :error
403+
@spec decode64(binary, ignore: :whitespace, padding: boolean) :: {:ok, binary} | :error
401404
def decode64(string, opts \\ []) when is_binary(string) do
402405
{:ok, decode64!(string, opts)}
403406
rescue
@@ -431,7 +434,7 @@ defmodule Base do
431434
"foob"
432435
433436
"""
434-
@spec decode64!(binary, keyword) :: binary
437+
@spec decode64!(binary, ignore: :whitespace, padding: boolean) :: binary
435438
def decode64!(string, opts \\ []) when is_binary(string) do
436439
pad? = Keyword.get(opts, :padding, true)
437440
string |> remove_ignored(opts[:ignore]) |> do_decode64(pad?)
@@ -453,7 +456,7 @@ defmodule Base do
453456
"_3_-_A"
454457
455458
"""
456-
@spec url_encode64(binary, keyword) :: binary
459+
@spec url_encode64(binary, padding: boolean) :: binary
457460
def url_encode64(data, opts \\ []) when is_binary(data) do
458461
pad? = Keyword.get(opts, :padding, true)
459462
do_encode64url(data, pad?)
@@ -481,7 +484,7 @@ defmodule Base do
481484
{:ok, <<255, 127, 254, 252>>}
482485
483486
"""
484-
@spec url_decode64(binary, keyword) :: {:ok, binary} | :error
487+
@spec url_decode64(binary, ignore: :whitespace, padding: boolean) :: {:ok, binary} | :error
485488
def url_decode64(string, opts \\ []) when is_binary(string) do
486489
{:ok, url_decode64!(string, opts)}
487490
rescue
@@ -513,7 +516,7 @@ defmodule Base do
513516
<<255, 127, 254, 252>>
514517
515518
"""
516-
@spec url_decode64!(binary, keyword) :: binary
519+
@spec url_decode64!(binary, ignore: :whitespace, padding: boolean) :: binary
517520
def url_decode64!(string, opts \\ []) when is_binary(string) do
518521
pad? = Keyword.get(opts, :padding, true)
519522
string |> remove_ignored(opts[:ignore]) |> do_decode64url(pad?)
@@ -551,7 +554,7 @@ defmodule Base do
551554
"MZXW6YTBOI"
552555
553556
"""
554-
@spec encode32(binary, keyword) :: binary
557+
@spec encode32(binary, case: encode_case, padding: boolean) :: binary
555558
def encode32(data, opts \\ []) when is_binary(data) do
556559
case = Keyword.get(opts, :case, :upper)
557560
pad? = Keyword.get(opts, :padding, true)
@@ -594,7 +597,7 @@ defmodule Base do
594597
{:ok, "foobar"}
595598
596599
"""
597-
@spec decode32(binary, keyword) :: {:ok, binary} | :error
600+
@spec decode32(binary, case: decode_case, padding: boolean) :: {:ok, binary} | :error
598601
def decode32(string, opts \\ []) do
599602
{:ok, decode32!(string, opts)}
600603
rescue
@@ -640,7 +643,7 @@ defmodule Base do
640643
"foobar"
641644
642645
"""
643-
@spec decode32!(binary, keyword) :: binary
646+
@spec decode32!(binary, case: decode_case, padding: boolean) :: binary
644647
def decode32!(string, opts \\ []) when is_binary(string) do
645648
case = Keyword.get(opts, :case, :upper)
646649
pad? = Keyword.get(opts, :padding, true)
@@ -680,7 +683,7 @@ defmodule Base do
680683
"CPNMUOJ1E8"
681684
682685
"""
683-
@spec hex_encode32(binary, keyword) :: binary
686+
@spec hex_encode32(binary, case: encode_case, padding: boolean) :: binary
684687
def hex_encode32(data, opts \\ []) when is_binary(data) do
685688
case = Keyword.get(opts, :case, :upper)
686689
pad? = Keyword.get(opts, :padding, true)
@@ -724,7 +727,7 @@ defmodule Base do
724727
{:ok, "foobar"}
725728
726729
"""
727-
@spec hex_decode32(binary, keyword) :: {:ok, binary} | :error
730+
@spec hex_decode32(binary, case: decode_case, padding: boolean) :: {:ok, binary} | :error
728731
def hex_decode32(string, opts \\ []) do
729732
{:ok, hex_decode32!(string, opts)}
730733
rescue
@@ -771,7 +774,7 @@ defmodule Base do
771774
"foobar"
772775
773776
"""
774-
@spec hex_decode32!(binary, keyword) :: binary
777+
@spec hex_decode32!(binary, case: decode_case, padding: boolean) :: binary
775778
def hex_decode32!(string, opts \\ []) when is_binary(string) do
776779
case = Keyword.get(opts, :case, :upper)
777780
pad? = Keyword.get(opts, :padding, true)

lib/elixir/test/elixir/base_test.exs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,21 @@ defmodule BaseTest do
799799
|> Enum.shuffle()
800800
|> IO.iodata_to_binary()
801801

802+
allowed_opts =
803+
encode
804+
|> Function.info()
805+
|> Keyword.fetch!(:name)
806+
|> case do
807+
:encode16 -> [:case]
808+
:encode64 -> [:padding]
809+
:url_encode64 -> [:padding]
810+
_ -> [:case, :padding]
811+
end
812+
802813
expected =
803814
data
804-
|> encode.(case: encode_case, pad: pad?)
805-
|> decode.(case: decode_case, pad: pad?)
815+
|> encode.(Keyword.take([case: encode_case, padding: pad?], allowed_opts))
816+
|> decode.(Keyword.take([case: decode_case, padding: pad?], allowed_opts))
806817

807818
assert data == expected,
808819
"identity did not match for #{inspect(data)} when #{inspect(encode)} (#{encode_case})"

0 commit comments

Comments
 (0)