diff options
author | sobolevn <mail@sobolevn.me> | 2024-08-20 21:34:59 +0300 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2024-08-24 13:07:53 +0100 |
commit | 644a7ae5a8823697808f9b3746774994c0f04990 (patch) | |
tree | 28334eb4da8c501ae68dd0558d95463321b6f09b | |
parent | e57ea3d5b73f9143071941ec0da0b6c38de7d86a (diff) | |
download | gleam_stdlib-644a7ae5a8823697808f9b3746774994c0f04990.tar.gz gleam_stdlib-644a7ae5a8823697808f9b3746774994c0f04990.zip |
Partially address review
-rw-r--r-- | src/gleam/bit_array.gleam | 26 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 6 | ||||
-rw-r--r-- | test/gleam/bit_array_test.gleam | 138 |
3 files changed, 32 insertions, 138 deletions
diff --git a/src/gleam/bit_array.gleam b/src/gleam/bit_array.gleam index cba8da9..9f03cc8 100644 --- a/src/gleam/bit_array.gleam +++ b/src/gleam/bit_array.gleam @@ -1,5 +1,6 @@ //// BitArrays are a sequence of binary data of any length. +@target(erlang) import gleam/int import gleam/order import gleam/string @@ -206,17 +207,14 @@ fn do_inspect(input: BitArray, accumulator: String) -> String { /// /// Only supported on Erlang target for now. /// -pub fn compare(a: BitArray, with b: BitArray) -> order.Order { - do_compare(a, b) -} - @external(javascript, "../gleam_stdlib.mjs", "bit_array_compare") -fn do_compare(a: BitArray, with b: BitArray) -> order.Order { +pub fn compare(a: BitArray, with b: BitArray) -> order.Order { case a, b { <<first_byte, first_rest:bits>>, <<second_byte, second_rest:bits>> -> - case int.compare(first_byte, second_byte) { - order.Eq -> compare(first_rest, second_rest) - result -> result + case first_byte, second_byte { + f, s if f > s -> order.Gt + f, s if f < s -> order.Lt + _, _ -> compare(first_rest, second_rest) } <<>>, <<>> -> order.Eq @@ -227,9 +225,15 @@ fn do_compare(a: BitArray, with b: BitArray) -> order.Order { // This happens when there's unusually sized elements. // Handle these special cases via custom erlang function. first, second -> - int.compare(bit_array_to_int(first), bit_array_to_int(second)) + case bit_array_to_int_and_size(first), bit_array_to_int_and_size(second) { + #(a, _), #(b, _) if a > b -> order.Gt + #(a, _), #(b, _) if a < b -> order.Lt + #(_, size_a), #(_, size_b) if size_a > size_b -> order.Gt + #(_, size_a), #(_, size_b) if size_a < size_b -> order.Lt + _, _ -> order.Eq + } } } -@external(erlang, "gleam_stdlib", "bit_array_to_int") -fn bit_array_to_int(a: BitArray) -> Int +@external(erlang, "gleam_stdlib", "bit_array_to_int_and_size") +fn bit_array_to_int_and_size(a: BitArray) -> #(Int, Int) diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index 96a35b7..1fc15b2 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -14,7 +14,7 @@ decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1, string_replace/3, regex_replace/3, slice/3, bit_array_to_int/1 + crop_string/2, base16_decode/1, string_replace/3, regex_replace/3, slice/3, bit_array_to_int_and_size/1 ]). %% Taken from OTP's uri_string module @@ -492,10 +492,10 @@ inspect_bit_array(Rest, Acc) -> Segment = <<X1/binary, ":size(", Size1/binary, ")">>, inspect_bit_array(<<>>, append_segment(Acc, Segment)). -bit_array_to_int(A) -> +bit_array_to_int_and_size(A) -> Size = bit_size(A), <<A1:Size>> = A, - A1. + {A1, Size}. append_segment(<<"<<">>, Segment) -> <<"<<", Segment/binary>>; diff --git a/test/gleam/bit_array_test.gleam b/test/gleam/bit_array_test.gleam index 553a8db..a563c15 100644 --- a/test/gleam/bit_array_test.gleam +++ b/test/gleam/bit_array_test.gleam @@ -334,127 +334,6 @@ pub fn inspect_partial_bytes_test() { } @target(erlang) -pub fn compare_test() { - bit_array.compare(<<1, 2, 3>>, <<1, 2, 3>>) - |> should.equal(order.Eq) - - bit_array.compare(<<1, 2>>, with: <<1, 3>>) - |> should.equal(order.Lt) - - bit_array.compare(<<1, 3>>, <<1, 2>>) - |> should.equal(order.Gt) - - bit_array.compare(<<1, 2>>, <<1, 2, 3>>) - |> should.equal(order.Lt) - - bit_array.compare(<<1, 2, 3>>, <<1, 2>>) - |> should.equal(order.Gt) -} - -pub fn compare_utf8_test() { - bit_array.compare(<<"ABC":utf8>>, <<"ABC":utf8>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"AB":utf8>>, <<"ABC":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"ABC":utf8>>, <<"AB":utf8>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"AB":utf8>>, <<"AC":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"AC":utf8>>, <<"AB":utf8>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"":utf8>>, <<"ABC":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"A":utf8>>, <<"":utf8>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"":utf8>>, <<"":utf8>>) - |> should.equal(order.Eq) -} - -pub fn compare_utf8_and_numbers_test() { - bit_array.compare(<<"A":utf8>>, <<65>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"A":utf8>>, <<64>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"A":utf8>>, <<66>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"AA":utf8>>, <<65, 65>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"AAA":utf8>>, <<65, 65>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"AA":utf8>>, <<65, 65, 1>>) - |> should.equal(order.Lt) -} - -@target(erlang) -pub fn compare_utf16_test() { - bit_array.compare(<<"ABC":utf16>>, <<"ABC":utf16>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"ABC":utf16>>, <<"AB":utf16>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"A":utf16>>, <<"Z":utf16>>) - |> should.equal(order.Lt) -} - -@target(erlang) -pub fn compare_utf32_test() { - bit_array.compare(<<"ABC":utf32>>, <<"ABC":utf32>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"ABC":utf32>>, <<"AB":utf32>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"A":utf32>>, <<"Z":utf32>>) - |> should.equal(order.Lt) -} - -@target(erlang) -pub fn compare_mixed_utfs_test() { - bit_array.compare(<<"A":utf16>>, <<"A":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"A":utf32>>, <<"A":utf16>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"A":utf8>>, <<"A":utf16>>) - |> should.equal(order.Gt) - - bit_array.compare(<<"":utf8>>, <<"A":utf16>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"":utf16>>, <<"A":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"":utf32>>, <<"A":utf8>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"":utf32>>, <<"A":utf16>>) - |> should.equal(order.Lt) - - bit_array.compare(<<"":utf16>>, <<"":utf8>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"":utf8>>, <<"":utf16>>) - |> should.equal(order.Eq) - - bit_array.compare(<<"":utf8>>, <<"":utf32>>) - |> should.equal(order.Eq) -} - -@target(erlang) pub fn compare_different_sizes_test() { bit_array.compare(<<4:5>>, <<4:5>>) |> should.equal(order.Eq) @@ -468,6 +347,14 @@ pub fn compare_different_sizes_test() { bit_array.compare(<<4:5, 3:3, 0:0>>, <<4:5, 3:3, 0:0>>) |> should.equal(order.Eq) + bit_array.compare(<<4:2, 3:4, 0:0>>, <<4:2, 3:3, 0:0>>) + |> should.equal(order.Gt) + + // first is: <<33, 1:size(1)>> + // second is: <<35>> + bit_array.compare(<<4:5, 3:4, 0:0>>, <<4:5, 3:3, 0:0>>) + |> should.equal(order.Lt) + bit_array.compare(<<3:5>>, <<4:5>>) |> should.equal(order.Lt) @@ -478,14 +365,17 @@ pub fn compare_different_sizes_test() { |> should.equal(order.Gt) bit_array.compare(<<4:8>>, <<4:5>>) - |> should.equal(order.Eq) + |> should.equal(order.Gt) bit_array.compare(<<4:5>>, <<4:8>>) - |> should.equal(order.Eq) + |> should.equal(order.Lt) bit_array.compare(<<0:5>>, <<0:8>>) + |> should.equal(order.Lt) + + bit_array.compare(<<0:5>>, <<0:5>>) |> should.equal(order.Eq) bit_array.compare(<<0:2>>, <<0:1>>) - |> should.equal(order.Eq) + |> should.equal(order.Gt) } |