aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsobolevn <mail@sobolevn.me>2024-08-20 21:34:59 +0300
committerLouis Pilfold <louis@lpil.uk>2024-08-24 13:07:53 +0100
commit644a7ae5a8823697808f9b3746774994c0f04990 (patch)
tree28334eb4da8c501ae68dd0558d95463321b6f09b
parente57ea3d5b73f9143071941ec0da0b6c38de7d86a (diff)
downloadgleam_stdlib-644a7ae5a8823697808f9b3746774994c0f04990.tar.gz
gleam_stdlib-644a7ae5a8823697808f9b3746774994c0f04990.zip
Partially address review
-rw-r--r--src/gleam/bit_array.gleam26
-rw-r--r--src/gleam_stdlib.erl6
-rw-r--r--test/gleam/bit_array_test.gleam138
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)
}