aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Saxton <peterhsaxton@gmail.com>2020-06-23 11:09:01 +0100
committerLouis Pilfold <louis@lpil.uk>2020-06-24 22:09:19 +0100
commit5077a4915893310e2f94a6541563529305e3cd28 (patch)
tree1f2ce90ba1219f858e0d55e20dec0d979b372df3
parent5017b8bff3097206d36bc6d5f28ce082649d4dbc (diff)
downloadgleam_stdlib-5077a4915893310e2f94a6541563529305e3cd28.tar.gz
gleam_stdlib-5077a4915893310e2f94a6541563529305e3cd28.zip
encode and decode functions for bas64
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/gleam/base.gleam24
-rw-r--r--src/gleam_stdlib.erl7
-rw-r--r--test/gleam/base_test.gleam52
4 files changed, 83 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b96f93b..25b47f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,7 +20,7 @@
- The `result` module gains the the `or` function.
- Created the `regex` module with the `from_string`, `from_string_with`, and
`match` functions.
- - The `list` module gains the the `pop`, `pop_map` and `key_pop` functions.
+- The `list` module gains the the `pop`, `pop_map` and `key_pop` functions.
## 0.9.0 - 2020-05-26
diff --git a/src/gleam/base.gleam b/src/gleam/base.gleam
new file mode 100644
index 0000000..8958184
--- /dev/null
+++ b/src/gleam/base.gleam
@@ -0,0 +1,24 @@
+import gleam/bit_string.{BitString}
+import gleam/string
+
+external fn erl_encode64(BitString) -> String =
+ "base64" "encode"
+
+external fn erl_decode64(String) -> Result(BitString, Nil) =
+ "gleam_stdlib" "base_decoded4"
+
+pub fn encode64(input: BitString, padding: Bool) -> String {
+ let encoded = erl_encode64(input)
+ case padding {
+ True -> encoded
+ False -> string.replace(encoded, "=", "")
+ }
+}
+
+pub fn decode64(encoded: String) -> Result(BitString, Nil) {
+ let padded = case bit_string.byte_size(bit_string.from_string(encoded)) % 4 {
+ 0 -> encoded
+ n -> string.append(encoded, string.repeat("=", 4 - n))
+ }
+ erl_decode64(padded)
+}
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index f0adbd0..47fbdb5 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -11,7 +11,7 @@
string_pad/4, decode_tuple2/1, decode_map/1, bit_string_int_to_u32/1,
bit_string_int_from_u32/1, bit_string_append/2, bit_string_part_/3,
decode_bit_string/1, regex_from_string/1, regex_from_string_with/2,
- regex_match/2]).
+ regex_match/2, base_decoded4/1]).
should_equal(Actual, Expected) -> ?assertEqual(Expected, Actual).
should_not_equal(Actual, Expected) -> ?assertNotEqual(Expected, Actual).
@@ -189,3 +189,8 @@ regex_match(Regex, String) ->
{match, _} -> true;
_ -> false
end.
+
+base_decoded4(S) ->
+ try {ok, base64:decode(S)} catch
+ error:badarith -> {error, nil}
+ end.
diff --git a/test/gleam/base_test.gleam b/test/gleam/base_test.gleam
new file mode 100644
index 0000000..90fdb2a
--- /dev/null
+++ b/test/gleam/base_test.gleam
@@ -0,0 +1,52 @@
+import gleam/base
+import gleam/bit_string.{BitString}
+import gleam/io
+import gleam/list
+import gleam/should
+
+external fn list_to_binary(List(Int)) -> BitString =
+ "erlang" "list_to_binary"
+
+pub fn encode64_test() {
+ [255, 127, 254, 252]
+ |> list_to_binary()
+ |> base.encode64(True)
+ |> should.equal("/3/+/A==")
+
+ [255, 127, 254, 252]
+ |> list_to_binary()
+ |> base.encode64(False)
+ |> should.equal("/3/+/A")
+
+ [0, 0, 0]
+ |> list_to_binary()
+ |> base.encode64(True)
+ |> should.equal("AAAA")
+
+ []
+ |> list_to_binary()
+ |> base.encode64(True)
+ |> should.equal("")
+}
+
+pub fn decode64_test() {
+ "/3/+/A=="
+ |> base.decode64()
+ |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+
+ "/3/+/A"
+ |> base.decode64()
+ |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+
+ "AAAA"
+ |> base.decode64()
+ |> should.equal(Ok(list_to_binary([0, 0, 0])))
+
+ ""
+ |> base.decode64()
+ |> should.equal(Ok(list_to_binary([])))
+
+ ")!"
+ |> base.decode64()
+ |> should.equal(Error(Nil))
+}