diff --git a/rebar.config.script b/rebar.config.script index 30bec74..a198c1c 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -34,6 +34,7 @@ Funs = [{application, get_supervisor, 1}, {binary, decode_hex, 1}, {binary, encode_hex, 1}, {binary, encode_hex, 2}, + {binary, join, 2}, {c, c, 3}, {c, erlangrc, 1}, {c, h, 1}, diff --git a/src/otpbp_binary.erl b/src/otpbp_binary.erl index 0c57108..c952eae 100644 --- a/src/otpbp_binary.erl +++ b/src/otpbp_binary.erl @@ -12,6 +12,10 @@ % OTP 25.3 -export([encode_hex/2]). -endif. +-ifndef(HAVE_binary__join_2). +% OTP 28.0 +-export([join/2]). +-endif. -ifndef(HAVE_binary__decode_hex_1). decode_hex(Bin) when byte_size(Bin) rem 2 =:= 0 -> @@ -51,3 +55,19 @@ encode_hex_digit(Char, uppercase) -> Char + ($A - 10); encode_hex_digit(Char, _lowercase) -> Char + ($a - 10). -endif. -endif. + +-ifndef(HAVE_binary__join_2). +join([], Separator) when is_binary(Separator) -> <<>>; +join([H], Separator) when is_binary(H), is_binary(Separator) -> H; +join([H|T] = List, Separator) when is_binary(Separator) -> + Acc = <<>>, %Enable private-append optimization + try + join(T, Separator, <>) + catch + error:_ -> error(badarg, [List, Separator]) + end; +join(Arg, Separator) -> error(badarg, [Arg, Separator]). + +join([], _Separator, Acc) -> Acc; +join([H|T], Separator, Acc) -> join(T, Separator, <>). +-endif. diff --git a/src/otpbp_pt.erl b/src/otpbp_pt.erl index 7225b0d..d2f4e3e 100644 --- a/src/otpbp_pt.erl +++ b/src/otpbp_pt.erl @@ -37,6 +37,7 @@ {{beam_lib, [strip, strip_files, strip_release], 2}, otpbp_beam_lib}, {{binary, decode_hex, 1}, otpbp_binary}, {{binary, encode_hex, [1, 2]}, otpbp_binary}, + {{binary, join, 2}, otpbp_binary}, {{c, c, 3}, otpbp_c}, {{c, erlangrc, 1}, otpbp_c}, {{c, [h, hcb, ht], [1, 2, 3]}, otpbp_c}, diff --git a/test/stdlib_tests.erl b/test/stdlib_tests.erl index 96c0eb5..f763a08 100644 --- a/test/stdlib_tests.erl +++ b/test/stdlib_tests.erl @@ -543,6 +543,17 @@ binary_test() -> ?assertEqual(<<"fooba">>, binary:decode_hex(<<"666f6f6261">>)), ?assertEqual(<<"foobar">>, binary:decode_hex(<<"666f6f626172">>)), ?assertEqual(<<"foobar">>, binary:decode_hex(<<"666f6F626172">>)), + % join/2 + ?assertEqual(<<"a, b, c">>, binary:join([<<"a">>, <<"b">>, <<"c">>], <<", ">>)), + ?assertEqual(<<"a">>, binary:join([<<"a">>], <<", ">>)), + ?assertEqual(<<>>, binary:join([], <<", ">>)), + ?assertError(badarg, maps:merge_with(not_a_fun, #{}, #{})), + ?assertError(badarg, binary:join(<<"">>, ",")), + ?assertError(badarg, binary:join([""], <<",">>)), + ?assertError(badarg, binary:join([123], <<",">>)), + ?assertError(badarg, binary:join(123, <<",">>)), + ?assertError(badarg, binary:join(#{}, <<",">>)), + ?assertError(badarg, binary:join(foo, <<",">>)), ok. ets_test() ->