aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/bit_array.gleam13
-rw-r--r--src/gleam_stdlib.mjs23
-rw-r--r--test/gleam/bit_array_test.gleam1
3 files changed, 36 insertions, 1 deletions
diff --git a/src/gleam/bit_array.gleam b/src/gleam/bit_array.gleam
index 909d9f1..8c3ce48 100644
--- a/src/gleam/bit_array.gleam
+++ b/src/gleam/bit_array.gleam
@@ -204,7 +204,18 @@ fn do_inspect(input: BitArray, accumulator: String) -> String {
/// // -> Eq
/// ```
///
+/// Only supported on Erlang target for now.
+///
pub fn compare(first: BitArray, second: BitArray) -> order.Order {
+ do_compare(first, second)
+}
+
+@target(javascript)
+@external(javascript, "../gleam_stdlib.mjs", "bit_array_compare")
+fn do_compare(first: BitArray, second: BitArray) -> order.Order
+
+@target(erlang)
+fn do_compare(first: BitArray, second: BitArray) -> order.Order {
case first, second {
<<first_byte, first_rest:bits>>, <<second_byte, second_rest:bits>> ->
int.compare(first_byte, second_byte)
@@ -217,11 +228,11 @@ pub fn compare(first: BitArray, second: BitArray) -> order.Order {
<<>>, _ -> order.Lt
// This happens when there's unusually sized elements.
// Handle these special cases via custom erlang function.
- // This cannot be reached in JS right now.
first, second ->
int.compare(bit_array_to_int(first), bit_array_to_int(second))
}
}
+@target(erlang)
@external(erlang, "gleam_stdlib", "bit_array_to_int")
fn bit_array_to_int(first: BitArray) -> Int
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs
index a89c829..9fe6caa 100644
--- a/src/gleam_stdlib.mjs
+++ b/src/gleam_stdlib.mjs
@@ -16,6 +16,7 @@ import {
} from "./gleam/regex.mjs";
import { DecodeError } from "./gleam/dynamic.mjs";
import { Some, None } from "./gleam/option.mjs";
+import { Eq, Gt, Lt } from "./gleam/order.mjs";
import Dict from "./dict.mjs";
const Nil = undefined;
@@ -916,3 +917,25 @@ export function base16_decode(string) {
export function bit_array_inspect(bits, acc) {
return `${acc}${[...bits.buffer].join(", ")}`;
}
+
+export function bit_array_compare(first, second) {
+ for (let i = 0; i < first.length; i++) {
+ if (i >= second.length) {
+ return new Gt(); // first has more items
+ }
+ const f = first.buffer[i];
+ const s = second.buffer[i];
+ if (f > s) {
+ return new Gt();
+ }
+ if (f < s) {
+ return new Lt()
+ }
+ }
+ // This means that either first did not have any items
+ // or all items in first were equal to second.
+ if (first.length === second.length) {
+ return new Eq();
+ }
+ return new Lt(); // second has more items
+}
diff --git a/test/gleam/bit_array_test.gleam b/test/gleam/bit_array_test.gleam
index 38dcb2e..5af8cee 100644
--- a/test/gleam/bit_array_test.gleam
+++ b/test/gleam/bit_array_test.gleam
@@ -333,6 +333,7 @@ pub fn inspect_partial_bytes_test() {
|> should.equal("<<182, 1:size(1)>>")
}
+@target(erlang)
pub fn compare_test() {
bit_array.compare(<<1, 2, 3>>, <<1, 2, 3>>)
|> should.equal(order.Eq)