aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2021-08-08 22:14:56 +0100
committerLouis Pilfold <louis@lpil.uk>2021-08-08 22:14:56 +0100
commit29398e1848b0615afda30fb1da4ec8d81eccc1c5 (patch)
tree5762a473ca246cee13adb1632b7d5850a91fd78c /src
parentc5a001977a3b76f257a3a7ea4605f6ff61f1a590 (diff)
downloadgleam_stdlib-29398e1848b0615afda30fb1da4ec8d81eccc1c5.tar.gz
gleam_stdlib-29398e1848b0615afda30fb1da4ec8d81eccc1c5.zip
Bit string slice
Diffstat (limited to 'src')
-rw-r--r--src/gleam/bit_string.gleam35
-rw-r--r--src/gleam_stdlib.erl4
-rw-r--r--src/gleam_stdlib.js14
3 files changed, 41 insertions, 12 deletions
diff --git a/src/gleam/bit_string.gleam b/src/gleam/bit_string.gleam
index 6605ce9..8ed94f8 100644
--- a/src/gleam/bit_string.gleam
+++ b/src/gleam/bit_string.gleam
@@ -45,19 +45,38 @@ pub fn append(to first: BitString, suffix second: BitString) -> BitString {
concat([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.
+///
+pub fn slice(
+ from string: BitString,
+ at position: Int,
+ take length: Int,
+) -> Result(BitString, Nil) {
+ do_slice(string, position, length)
+}
+
if erlang {
- /// Extracts part of a bit string.
- ///
- /// BitString part 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.
- ///
- pub external fn part(
+ pub external fn do_slice(
+ string: BitString,
+ position: Int,
+ length: Int,
+ ) -> Result(BitString, Nil) =
+ "gleam_stdlib" "bit_string_slice"
+}
+
+if javascript {
+ pub external fn do_slice(
string: BitString,
position: Int,
length: Int,
) -> Result(BitString, Nil) =
- "gleam_stdlib" "bit_string_part_"
+ "../gleam_stdlib.js" "bit_string_slice"
}
/// Tests to see whether a bit string is valid UTF-8.
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index c3aa317..13968d2 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -9,7 +9,7 @@
string_ends_with/2, string_pad/4, decode_tuple2/1, decode_tuple3/1,
decode_tuple4/1, decode_tuple5/1, decode_tuple6/1, decode_map/1,
bit_string_int_to_u32/1, bit_string_int_from_u32/1, decode_result/1,
- bit_string_part_/3, decode_bit_string/1, compile_regex/2,
+ bit_string_slice/3, decode_bit_string/1, compile_regex/2,
regex_match/2, regex_split/2, regex_scan/2, base_decode64/1,
wrap_list/1, bit_string_concat/1]).
@@ -174,7 +174,7 @@ string_pop_grapheme(String) ->
bit_string_concat(BitStrings) ->
iolist_to_binary(BitStrings).
-bit_string_part_(Bin, Pos, Len) ->
+bit_string_slice(Bin, Pos, Len) ->
try {ok, binary:part(Bin, Pos, Len)}
catch error:badarg -> {error, nil}
end.
diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js
index b63a4ea..51de04a 100644
--- a/src/gleam_stdlib.js
+++ b/src/gleam_stdlib.js
@@ -213,8 +213,11 @@ export function log(term) {
}
export function stringify(data) {
- let replacer = (_key, value) =>
- typeof value === "bigint" ? value.toString() + "n" : value;
+ let replacer = (_key, value) => {
+ if (typeof value === "bigint") return value.toString() + "n";
+ if (typeof value === "undefined") return null;
+ return value;
+ };
try {
return JSON.stringify(data, replacer);
} catch (_error) {
@@ -263,3 +266,10 @@ export function truncate(float) {
export function power(base, exponent) {
return Math.pow(base, exponent);
}
+
+export function bit_string_slice(bits, position, length) {
+ let start = Math.min(position, position + length);
+ let end = Math.max(position, position + length);
+ if (start < 0 || end > bits.byteLength) return gleam_error(Nil);
+ return gleam_ok(new Uint8Array(bits.buffer, start, Math.abs(length)));
+}