aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2023-10-19 21:47:19 +0100
committerLouis Pilfold <louis@lpil.uk>2023-10-26 12:24:40 +0100
commitb713e6fd185ad8b4da90f4b686aa9ecf0f60f0e4 (patch)
tree65e58212b32e5d2e6bbff81aaa050aacb82bb357
parentb181a406b5bc4e1855a1455b9d603d30320f1b54 (diff)
downloadgleam_stdlib-b713e6fd185ad8b4da90f4b686aa9ecf0f60f0e4.tar.gz
gleam_stdlib-b713e6fd185ad8b4da90f4b686aa9ecf0f60f0e4.zip
Run gleam fix, make bit_array module
-rw-r--r--gleam.toml2
-rw-r--r--src/gleam/base.gleam12
-rw-r--r--src/gleam/bit_array.gleam102
-rw-r--r--src/gleam/bit_builder.gleam31
-rw-r--r--src/gleam/bit_string.gleam133
-rw-r--r--src/gleam/bool.gleam2
-rw-r--r--src/gleam/dynamic.gleam8
-rw-r--r--src/gleam/float.gleam2
-rw-r--r--src/gleam/int.gleam2
-rw-r--r--src/gleam/iterator.gleam4
-rw-r--r--src/gleam/list.gleam4
-rw-r--r--src/gleam/map.gleam2
-rw-r--r--src/gleam/regex.gleam2
-rw-r--r--src/gleam/set.gleam2
-rw-r--r--src/gleam/string.gleam21
-rw-r--r--src/gleam/uri.gleam4
-rw-r--r--test/gleam/bit_array_test.gleam135
-rw-r--r--test/gleam/string_test.gleam2
18 files changed, 310 insertions, 160 deletions
diff --git a/gleam.toml b/gleam.toml
index b4d51ab..51feaf3 100644
--- a/gleam.toml
+++ b/gleam.toml
@@ -1,6 +1,6 @@
name = "gleam_stdlib"
version = "0.31.0"
-gleam = ">= 0.30.0"
+gleam = ">= 0.32.0"
licences = ["Apache-2.0"]
description = "A standard library for the Gleam programming language"
diff --git a/src/gleam/base.gleam b/src/gleam/base.gleam
index a084a7c..5877f3d 100644
--- a/src/gleam/base.gleam
+++ b/src/gleam/base.gleam
@@ -3,7 +3,7 @@ import gleam/string
/// Encodes a BitString into a base 64 encoded string.
///
-pub fn encode64(input: BitString, padding: Bool) -> String {
+pub fn encode64(input: BitArray, padding: Bool) -> String {
let encoded = do_encode64(input)
case padding {
True -> encoded
@@ -13,11 +13,11 @@ pub fn encode64(input: BitString, padding: Bool) -> String {
@external(erlang, "base64", "encode")
@external(javascript, "../gleam_stdlib.mjs", "encode64")
-fn do_encode64(a: BitString) -> String
+fn do_encode64(a: BitArray) -> String
/// Decodes a base 64 encoded string into a `BitString`.
///
-pub fn decode64(encoded: String) -> Result(BitString, Nil) {
+pub fn decode64(encoded: String) -> Result(BitArray, Nil) {
let padded = case bit_string.byte_size(bit_string.from_string(encoded)) % 4 {
0 -> encoded
n -> string.append(encoded, string.repeat("=", 4 - n))
@@ -27,11 +27,11 @@ pub fn decode64(encoded: String) -> Result(BitString, Nil) {
@external(erlang, "gleam_stdlib", "base_decode64")
@external(javascript, "../gleam_stdlib.mjs", "decode64")
-fn do_decode64(a: String) -> Result(BitString, Nil)
+fn do_decode64(a: String) -> Result(BitArray, Nil)
/// Encodes a `BitString` into a base 64 encoded string with URL and filename safe alphabet.
///
-pub fn url_encode64(input: BitString, padding: Bool) -> String {
+pub fn url_encode64(input: BitArray, padding: Bool) -> String {
encode64(input, padding)
|> string.replace("+", "-")
|> string.replace("/", "_")
@@ -39,7 +39,7 @@ pub fn url_encode64(input: BitString, padding: Bool) -> String {
/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitString`.
///
-pub fn url_decode64(encoded: String) -> Result(BitString, Nil) {
+pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) {
encoded
|> string.replace("-", "+")
|> string.replace("_", "/")
diff --git a/src/gleam/bit_array.gleam b/src/gleam/bit_array.gleam
new file mode 100644
index 0000000..6ea94d8
--- /dev/null
+++ b/src/gleam/bit_array.gleam
@@ -0,0 +1,102 @@
+//// BitArrays are a sequence of binary data of any length.
+
+/// Converts a UTF-8 `String` type into a `BitArray`.
+///
+@external(erlang, "gleam_stdlib", "identity")
+@external(javascript, "../gleam_stdlib.mjs", "bit_string_from_string")
+pub fn from_string(x: String) -> BitArray
+
+/// Returns an integer which is the number of bytes in the bit array.
+///
+@external(erlang, "erlang", "byte_size")
+@external(javascript, "../gleam_stdlib.mjs", "length")
+pub fn byte_size(x: BitArray) -> Int
+
+/// Creates a new bit array by joining two bit arrays.
+///
+/// ## Examples
+///
+/// ```gleam
+/// > append(to: from_string("butter"), suffix: from_string("fly"))
+/// from_string("butterfly")
+/// ```
+///
+pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray {
+ concat([first, second])
+}
+
+/// Extracts a sub-section of a bit array.
+///
+/// The slice will start at given position and continue up to specified
+/// length.
+/// A negative length can be used to extract bytes at the end of a bit array.
+///
+/// This function runs in constant time.
+///
+@external(erlang, "gleam_stdlib", "bit_string_slice")
+@external(javascript, "../gleam_stdlib.mjs", "bit_string_slice")
+pub fn slice(
+ from string: BitArray,
+ at position: Int,
+ take length: Int,
+) -> Result(BitArray, Nil)
+
+/// Tests to see whether a bit array is valid UTF-8.
+///
+pub fn is_utf8(bits: BitArray) -> Bool {
+ do_is_utf8(bits)
+}
+
+@target(erlang)
+fn do_is_utf8(bits: BitArray) -> Bool {
+ case bits {
+ <<>> -> True
+ <<_:utf8, rest:bytes>> -> do_is_utf8(rest)
+ _ -> False
+ }
+}
+
+@target(javascript)
+fn do_is_utf8(bits: BitArray) -> Bool {
+ case to_string(bits) {
+ Ok(_) -> True
+ _ -> False
+ }
+}
+
+/// Converts a bit array to a string.
+///
+/// Returns an error if the bit array is invalid UTF-8 data.
+///
+pub fn to_string(bits: BitArray) -> Result(String, Nil) {
+ do_to_string(bits)
+}
+
+@target(erlang)
+@external(erlang, "gleam_stdlib", "identity")
+fn unsafe_to_string(a: BitArray) -> String
+
+@target(erlang)
+fn do_to_string(bits: BitArray) -> Result(String, Nil) {
+ case is_utf8(bits) {
+ True -> Ok(unsafe_to_string(bits))
+ False -> Error(Nil)
+ }
+}
+
+@target(javascript)
+@external(javascript, "../gleam_stdlib.mjs", "bit_string_to_string")
+fn do_to_string(a: BitArray) -> Result(String, Nil)
+
+/// Creates a new bit array by joining multiple binaries.
+///
+/// ## Examples
+///
+/// ```gleam
+/// > concat([from_string("butter"), from_string("fly")])
+/// from_string("butterfly")
+/// ```
+///
+@external(erlang, "gleam_stdlib", "bit_string_concat")
+@external(javascript, "../gleam_stdlib.mjs", "bit_string_concat")
+pub fn concat(bit_strings: List(BitArray)) -> BitArray
diff --git a/src/gleam/bit_builder.gleam b/src/gleam/bit_builder.gleam
index b880334..319a823 100644
--- a/src/gleam/bit_builder.gleam
+++ b/src/gleam/bit_builder.gleam
@@ -12,7 +12,7 @@
////
//// On Erlang this type is compatible with Erlang's iolists.
-import gleam/string_builder.{StringBuilder}
+import gleam/string_builder.{type StringBuilder}
@target(javascript)
import gleam/list
@target(javascript)
@@ -23,7 +23,7 @@ pub type BitBuilder
@target(javascript)
pub opaque type BitBuilder {
- Bits(BitString)
+ Bits(BitArray)
Text(StringBuilder)
Many(List(BitBuilder))
}
@@ -39,7 +39,7 @@ pub fn new() -> BitBuilder {
///
/// Runs in constant time.
///
-pub fn prepend(to: BitBuilder, prefix: BitString) -> BitBuilder {
+pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder {
append_builder(from_bit_string(prefix), to)
}
@@ -47,7 +47,7 @@ pub fn prepend(to: BitBuilder, prefix: BitString) -> BitBuilder {
///
/// Runs in constant time.
///
-pub fn append(to: BitBuilder, suffix: BitString) -> BitBuilder {
+pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder {
append_builder(to, from_bit_string(suffix))
}
@@ -121,16 +121,16 @@ fn do_concat(builders: List(BitBuilder)) -> BitBuilder {
///
/// Runs in constant time.
///
-pub fn concat_bit_strings(bits: List(BitString)) -> BitBuilder {
+pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder {
do_concat_bit_strings(bits)
}
@target(erlang)
@external(erlang, "gleam_stdlib", "identity")
-fn do_concat_bit_strings(a: List(BitString)) -> BitBuilder
+fn do_concat_bit_strings(a: List(BitArray)) -> BitBuilder
@target(javascript)
-fn do_concat_bit_strings(bits: List(BitString)) -> BitBuilder {
+fn do_concat_bit_strings(bits: List(BitArray)) -> BitBuilder {
bits
|> list.map(fn(b) { from_bit_string(b) })
|> concat()
@@ -176,16 +176,16 @@ fn do_from_string_builder(builder: StringBuilder) -> BitBuilder {
///
/// Runs in constant time.
///
-pub fn from_bit_string(bits: BitString) -> BitBuilder {
+pub fn from_bit_string(bits: BitArray) -> BitBuilder {
do_from_bit_string(bits)
}
@target(erlang)
@external(erlang, "gleam_stdlib", "wrap_list")
-fn do_from_bit_string(a: BitString) -> BitBuilder
+fn do_from_bit_string(a: BitArray) -> BitBuilder
@target(javascript)
-fn do_from_bit_string(bits: BitString) -> BitBuilder {
+fn do_from_bit_string(bits: BitArray) -> BitBuilder {
Bits(bits)
}
@@ -196,16 +196,16 @@ fn do_from_bit_string(bits: BitString) -> BitBuilder {
/// When running on Erlang this function is implemented natively by the
/// virtual machine and is highly optimised.
///
-pub fn to_bit_string(builder: BitBuilder) -> BitString {
+pub fn to_bit_string(builder: BitBuilder) -> BitArray {
do_to_bit_string(builder)
}
@target(erlang)
@external(erlang, "erlang", "list_to_bitstring")
-fn do_to_bit_string(a: BitBuilder) -> BitString
+fn do_to_bit_string(a: BitBuilder) -> BitArray
@target(javascript)
-fn do_to_bit_string(builder: BitBuilder) -> BitString {
+fn do_to_bit_string(builder: BitBuilder) -> BitArray {
[[builder]]
|> to_list([])
|> list.reverse
@@ -213,10 +213,7 @@ fn do_to_bit_string(builder: BitBuilder) -> BitString {
}
@target(javascript)
-fn to_list(
- stack: List(List(BitBuilder)),
- acc: List(BitString),
-) -> List(BitString) {
+fn to_list(stack: List(List(BitBuilder)), acc: List(BitArray)) -> List(BitArray) {
case stack {
[] -> acc
diff --git a/src/gleam/bit_string.gleam b/src/gleam/bit_string.gleam
index 25ad686..b703da0 100644
--- a/src/gleam/bit_string.gleam
+++ b/src/gleam/bit_string.gleam
@@ -1,124 +1,43 @@
-//// Working with raw bit string data.
-//// The `BitString` type should be used instead of a String type when not utf8
-//// encoded.
+//// This module has been deprecated. Please use the `gleam/bit_array` module
+//// instead.
-/// Converts a UTF-8 `String` type into a raw `BitString` type.
-///
-pub fn from_string(x: String) -> BitString {
- do_from_string(x)
-}
-
-@external(erlang, "gleam_stdlib", "identity")
-@external(javascript, "../gleam_stdlib.mjs", "bit_string_from_string")
-fn do_from_string(a: String) -> BitString
+import gleam/bit_array
-/// Returns an integer which is the number of bytes in the bit string.
-///
-pub fn byte_size(x: BitString) -> Int {
- do_byte_size(x)
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn from_string(x: String) -> BitArray {
+ bit_array.from_string(x)
}
-@external(erlang, "erlang", "byte_size")
-@external(javascript, "../gleam_stdlib.mjs", "length")
-fn do_byte_size(a: BitString) -> Int
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn byte_size(x: BitArray) -> Int {
+ bit_array.byte_size(x)
+}
-/// Creates a new bit string by joining two binaries.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > append(to: from_string("butter"), suffix: from_string("fly"))
-/// from_string("butterfly")
-/// ```
-///
-pub fn append(to first: BitString, suffix second: BitString) -> BitString {
- concat([first, second])
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray {
+ bit_array.append(first, second)
}
-/// Extracts a sub-section of a bit string.
-///
-/// The slice will start at given position and continue up to specified
-/// length.
-/// A negative length can be used to extract bytes at the end of a bit string.
-///
-/// This function runs in constant time.
-///
+@deprecated("Please use the `gleam/bit_array` module instead.")
pub fn slice(
- from string: BitString,
+ from string: BitArray,
at position: Int,
take length: Int,
-) -> Result(BitString, Nil) {
- do_slice(string, position, length)
+) -> Result(BitArray, Nil) {
+ bit_array.slice(string, position, length)
}
-@external(erlang, "gleam_stdlib", "bit_string_slice")
-@external(javascript, "../gleam_stdlib.mjs", "bit_string_slice")
-fn do_slice(
- string string: BitString,
- position position: Int,
- length length: Int,
-) -> Result(BitString, Nil)
-
-/// Tests to see whether a bit string is valid UTF-8.
-///
-pub fn is_utf8(bits: BitString) -> Bool {
- do_is_utf8(bits)
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn is_utf8(bits: BitArray) -> Bool {
+ bit_array.is_utf8(bits)
}
-@target(erlang)
-fn do_is_utf8(bits: BitString) -> Bool {
- case bits {
- <<>> -> True
- <<_:utf8, rest:binary>> -> do_is_utf8(rest)
- _ -> False
- }
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn to_string(bits: BitArray) -> Result(String, Nil) {
+ bit_array.to_string(bits)
}
-@target(javascript)
-fn do_is_utf8(bits: BitString) -> Bool {
- case to_string(bits) {
- Ok(_) -> True
- _ -> False
- }
+@deprecated("Please use the `gleam/bit_array` module instead.")
+pub fn concat(bit_strings: List(BitArray)) -> BitArray {
+ bit_array.concat(bit_strings)
}
-
-/// Converts a bit string to a string.
-///
-/// Returns an error if the bit string is invalid UTF-8 data.
-///
-pub fn to_string(bits: BitString) -> Result(String, Nil) {
- do_to_string(bits)
-}
-
-@target(erlang)
-@external(erlang, "gleam_stdlib", "identity")
-fn unsafe_to_string(a: BitString) -> String
-
-@target(erlang)
-fn do_to_string(bits: BitString) -> Result(String, Nil) {
- case is_utf8(bits) {
- True -> Ok(unsafe_to_string(bits))
- False -> Error(Nil)
- }
-}
-
-@target(javascript)
-@external(javascript, "../gleam_stdlib.mjs", "bit_string_to_string")
-fn do_to_string(a: BitString) -> Result(String, Nil)
-
-/// Creates a new bit string by joining multiple binaries.
-///
-/// ## Examples
-///
-/// ```gleam
-/// > concat([from_string("butter"), from_string("fly")])
-/// from_string("butterfly")
-/// ```
-///
-pub fn concat(bit_strings: List(BitString)) -> BitString {
- do_concat(bit_strings)
-}
-
-@external(erlang, "gleam_stdlib", "bit_string_concat")
-@external(javascript, "../gleam_stdlib.mjs", "bit_string_concat")
-fn do_concat(a: List(BitString)) -> BitString
diff --git a/src/gleam/bool.gleam b/src/gleam/bool.gleam
index 66200a8..2cbe8a3 100644
--- a/src/gleam/bool.gleam
+++ b/src/gleam/bool.gleam
@@ -6,7 +6,7 @@
//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom
//// type that can be either `Student` or `Teacher`.
-import gleam/order.{Order}
+import gleam/order.{type Order}
/// Returns the and of two bools, but it evaluates both arguments.
///
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index 80ddd87..d12f85c 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -1,7 +1,7 @@
import gleam/int
import gleam/list
-import gleam/map.{Map}
-import gleam/option.{Option}
+import gleam/map.{type Map}
+import gleam/option.{type Option}
import gleam/result
import gleam/string_builder
@target(erlang)
@@ -75,13 +75,13 @@ pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) {
/// Error([DecodeError(expected: "BitString", found: "Int", path: [])])
/// ```
///
-pub fn bit_string(from data: Dynamic) -> Result(BitString, DecodeErrors) {
+pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) {
decode_bit_string(data)
}
@external(erlang, "gleam_stdlib", "decode_bit_string")
@external(javascript, "../gleam_stdlib.mjs", "decode_bit_string")
-fn decode_bit_string(a: Dynamic) -> Result(BitString, DecodeErrors)
+fn decode_bit_string(a: Dynamic) -> Result(BitArray, DecodeErrors)
/// Checks to see whether a `Dynamic` value is a string, and returns that string if
/// it is.
diff --git a/src/gleam/float.gleam b/src/gleam/float.gleam
index c8c6147..59789fc 100644
--- a/src/gleam/float.gleam
+++ b/src/gleam/float.gleam
@@ -1,4 +1,4 @@
-import gleam/order.{Order}
+import gleam/order.{type Order}
/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was
/// not possible.
diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam
index e440365..8b3b89e 100644
--- a/src/gleam/int.gleam
+++ b/src/gleam/int.gleam
@@ -1,5 +1,5 @@
import gleam/float
-import gleam/order.{Order}
+import gleam/order.{type Order}
/// Returns the absolute value of the input.
///
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam
index 069c75b..4e9d82a 100644
--- a/src/gleam/iterator.gleam
+++ b/src/gleam/iterator.gleam
@@ -1,8 +1,8 @@
import gleam/result
import gleam/int
import gleam/list
-import gleam/map.{Map}
-import gleam/option.{None, Option, Some}
+import gleam/map.{type Map}
+import gleam/option.{type Option, None, Some}
import gleam/order
// Internal private representation of an Iterator
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index e0c50ef..0b4c627 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -24,9 +24,9 @@
import gleam/int
import gleam/float
-import gleam/order.{Order}
+import gleam/order.{type Order}
import gleam/pair
-import gleam/map.{Map}
+import gleam/map.{type Map}
/// An error value returned by the `strict_zip` function.
///
diff --git a/src/gleam/map.gleam b/src/gleam/map.gleam
index 7969f5e..21ac4f8 100644
--- a/src/gleam/map.gleam
+++ b/src/gleam/map.gleam
@@ -1,4 +1,4 @@
-import gleam/option.{Option}
+import gleam/option.{type Option}
/// A dictionary of keys and values.
///
diff --git a/src/gleam/regex.gleam b/src/gleam/regex.gleam
index 10b09e2..9ffda78 100644
--- a/src/gleam/regex.gleam
+++ b/src/gleam/regex.gleam
@@ -3,7 +3,7 @@
//// all of the PCRE library is interfaced and some parts of the library go beyond
//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used.
-import gleam/option.{Option}
+import gleam/option.{type Option}
pub type Regex
diff --git a/src/gleam/set.gleam b/src/gleam/set.gleam
index 065ff34..8e33e37 100644
--- a/src/gleam/set.gleam
+++ b/src/gleam/set.gleam
@@ -1,5 +1,5 @@
import gleam/list
-import gleam/map.{Map}
+import gleam/map.{type Map}
import gleam/result
// A list is used as the map value as an empty list has the smallest
diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam
index 5a85cc3..97acf4e 100644
--- a/src/gleam/string.gleam
+++ b/src/gleam/string.gleam
@@ -1,15 +1,15 @@
//// Strings in Gleam are UTF-8 binaries. They can be written in your code as
//// text surrounded by `"double quotes"`.
-import gleam/iterator.{Iterator}
+import gleam/iterator.{type Iterator}
import gleam/list
-import gleam/option.{None, Option, Some}
+import gleam/option.{type Option, None, Some}
import gleam/order
-import gleam/string_builder.{StringBuilder}
+import gleam/string_builder.{type StringBuilder}
@target(erlang)
import gleam/bit_string
@target(erlang)
-import gleam/dynamic.{Dynamic}
+import gleam/dynamic.{type Dynamic}
@target(erlang)
import gleam/result
@@ -761,11 +761,11 @@ fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) {
@target(erlang)
fn do_to_utf_codepoints_impl(
- bit_string: BitString,
+ bit_string: BitArray,
acc: List(UtfCodepoint),
) -> List(UtfCodepoint) {
case bit_string {
- <<first:utf8_codepoint, rest:binary>> ->
+ <<first:utf8_codepoint, rest:bytes>> ->
do_to_utf_codepoints_impl(rest, [first, ..acc])
<<>> -> acc
}
@@ -818,14 +818,11 @@ fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String {
@target(erlang)
fn do_from_utf_codepoints_impl(
utf_codepoints: List(UtfCodepoint),
- acc: BitString,
-) -> BitString {
+ acc: BitArray,
+) -> BitArray {
case utf_codepoints {
[first, ..rest] ->
- do_from_utf_codepoints_impl(
- rest,
- <<acc:bit_string, first:utf8_codepoint>>,
- )
+ do_from_utf_codepoints_impl(rest, <<acc:bits, first:utf8_codepoint>>)
[] -> acc
}
}
diff --git a/src/gleam/uri.gleam b/src/gleam/uri.gleam
index 2565771..3d817eb 100644
--- a/src/gleam/uri.gleam
+++ b/src/gleam/uri.gleam
@@ -9,9 +9,9 @@
import gleam/int
import gleam/list
-import gleam/option.{None, Option, Some}
+import gleam/option.{type Option, None, Some}
import gleam/string
-import gleam/string_builder.{StringBuilder}
+import gleam/string_builder.{type StringBuilder}
@target(javascript)
import gleam/pair
@target(javascript)
diff --git a/test/gleam/bit_array_test.gleam b/test/gleam/bit_array_test.gleam
new file mode 100644
index 0000000..65a8009
--- /dev/null
+++ b/test/gleam/bit_array_test.gleam
@@ -0,0 +1,135 @@
+import gleam/bit_array
+import gleam/should
+
+pub fn byte_size_test() {
+ bit_array.byte_size(bit_array.from_string("hello"))
+ |> should.equal(5)
+
+ bit_array.byte_size(bit_array.from_string(""))
+ |> should.equal(0)
+}
+
+pub fn not_equal_test() {
+ bit_array.from_string("test")
+ |> should.not_equal(bit_array.from_string("asdf"))
+}
+
+pub fn append_test() {
+ bit_array.from_string("Test")
+ |> bit_array.append(bit_array.from_string(" Me"))
+ |> should.equal(bit_array.from_string("Test Me"))
+
+ <<1, 2>>
+ |> bit_array.append(<<>>)
+ |> should.equal(<<1, 2>>)
+
+ <<1, 2>>
+ |> bit_array.append(<<3, 4>>)
+ |> should.equal(<<1, 2, 3, 4>>)
+}
+
+@target(erlang)
+pub fn append_erlang_only_test() {
+ <<1, 2:4>>
+ |> bit_array.append(<<3>>)
+ |> should.equal(<<1, 2:4, 3>>)
+}
+
+pub fn concat_test() {
+ [<<1, 2>>]
+ |> bit_array.concat
+ |> should.equal(<<1, 2>>)
+
+ [<<1, 2>>, <<3>>, <<4>>]
+ |> bit_array.concat
+ |> should.equal(<<1, 2, 3, 4>>)
+}
+
+@target(erlang)
+pub fn concat_erlang_only_test() {
+ [<<1, 2:4>>, <<3>>]
+ |> bit_array.concat
+ |> should.equal(<<1, 2:4, 3>>)
+}
+
+pub fn slice_test() {
+ <<"hello":utf8>>
+ |> bit_array.slice(0, 5)
+ |> should.equal(Ok(<<"hello":utf8>>))
+
+ <<"hello":utf8>>
+ |> bit_array.slice(0, 0)
+ |> should.equal(Ok(<<"":utf8>>))
+
+ <<"hello":utf8>>
+ |> bit_array.slice(2, 2)
+ |> should.equal(Ok(<<"ll":utf8>>))
+
+ <<"hello":utf8>>
+ |> bit_array.slice(5, -2)
+ |> should.equal(Ok(<<"lo":utf8>>))
+
+ <<"":utf8>>
+ |> bit_array.slice(0, 0)
+ |> should.equal(Ok(<<"":utf8>>))
+
+ <<"hello":utf8>>
+ |> bit_array.slice(6, 0)
+ |> should.equal(Error(Nil))
+
+ <<"hello":utf8>>
+ |> bit_array.slice(1, -2)
+ |> should.equal(Error(Nil))
+
+ bit_array.from_string("hello")
+ |> bit_array.slice(-1, 1)
+ |> should.equal(Error(Nil))
+
+ bit_array.from_string("hello")
+ |> bit_array.slice(1, 6)
+ |> should.equal(Error(Nil))
+}
+
+pub fn to_string_test() {
+ <<>>
+ |> bit_array.to_string
+ |> should.equal(Ok(""))
+
+ <<"":utf8>>
+ |> bit_array.to_string
+ |> should.equal(Ok(""))
+
+ <<"Hello":utf8>>
+ |> bit_array.to_string
+ |> should.equal(Ok("Hello"))
+
+ <<"ø":utf8>>
+ |> bit_array.to_string
+ |> should.equal(Ok("ø"))
+
+ <<65_535>>
+ |> bit_array.to_string
+ |> should.equal(Error(Nil))
+}
+
+pub fn is_utf8_test() {
+ <<>>
+ |> bit_array.is_utf8
+ |> should.be_true
+
+ <<"":utf8>>
+ |> bit_array.is_utf8
+ |> should.be_true
+
+ <<"Hello":utf8>>
+ |> bit_array.is_utf8
+ |> should.be_true
+
+ <<"ø":utf8>>
+ |> bit_array.is_utf8
+ |> should.be_true
+
+ <<65_535>>
+ |> bit_array.is_utf8
+ |> should.be_false
+}
diff --git a/test/gleam/string_test.gleam b/test/gleam/string_test.gleam
index 88eb39b..f4ff645 100644
--- a/test/gleam/string_test.gleam
+++ b/test/gleam/string_test.gleam
@@ -917,7 +917,7 @@ pub fn target_inspect_test() {
@target(erlang)
import gleam/regex
@target(erlang)
-import gleam/dynamic.{Dynamic}
+import gleam/dynamic.{type Dynamic}
// Test inspect on Erlang atoms valid and invalid in Gleam