Skip to content

Commit 4200c55

Browse files
committed
v1.1.0
1 parent d415550 commit 4200c55

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v1.1.0 - 2025-06-25
4+
5+
- The `gleam/erlang/atom` module gains the `to_dynamic` and `decoder` functions.
6+
37
## v1.0.0 - 2025-06-12
48

59
- The `gleam/erlang/node` module gains the `name` function.

gleam.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "gleam_erlang"
22

3-
version = "1.0.0"
3+
version = "1.1.0"
44
licences = ["Apache-2.0"]
55
description = "Types and functions for programs running on Erlang!"
66

src/gleam/erlang/atom.gleam

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import gleam/dynamic
2+
import gleam/dynamic/decode
3+
14
/// Atom is a special string-like data-type that is most commonly used for
25
/// interfacing with code written in other BEAM languages such as Erlang and
36
/// Elixir. It is preferable to define your own custom types to use instead of
@@ -47,3 +50,32 @@ pub fn create(a: String) -> Atom
4750
///
4851
@external(erlang, "erlang", "atom_to_binary")
4952
pub fn to_string(a: Atom) -> String
53+
54+
/// Convert an atom to a dynamic value, throwing away the type information.
55+
///
56+
/// This may be useful for testing decoders.
57+
///
58+
@external(erlang, "gleam_erlang_ffi", "identity")
59+
pub fn to_dynamic(a: Atom) -> dynamic.Dynamic
60+
61+
@external(erlang, "gleam_erlang_ffi", "identity")
62+
pub fn cast_from_dynamic(a: dynamic.Dynamic) -> Atom
63+
64+
/// A dynamic decoder for atoms.
65+
///
66+
/// You almost certainly should not use this to work with externally defined
67+
/// functions. They return known types, so you should define the external
68+
/// functions with the correct types, defining wrapper functions in Erlang if
69+
/// the external types cannot be mapped directly onto Gleam types.
70+
///
71+
pub fn decoder() -> decode.Decoder(Atom) {
72+
decode.new_primitive_decoder("Atom", fn(data) {
73+
case is_atom(data) {
74+
True -> Ok(cast_from_dynamic(data))
75+
False -> Error(create("nil"))
76+
}
77+
})
78+
}
79+
80+
@external(erlang, "erlang", "is_atom")
81+
fn is_atom(data: dynamic.Dynamic) -> Bool

test/gleam/erlang/atom_test.gleam

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import gleam/dynamic
2+
import gleam/dynamic/decode
13
import gleam/erlang/atom
24
import gleam/int
35

@@ -22,3 +24,11 @@ pub fn to_string_test() {
2224
let assert "ok" = atom.to_string(atom.create("ok"))
2325
let assert "expect" = atom.to_string(atom.create("expect"))
2426
}
27+
28+
pub fn dynamic_test() {
29+
let wibble = atom.create("wibble")
30+
31+
assert decode.run(atom.to_dynamic(wibble), atom.decoder()) == Ok(wibble)
32+
assert decode.run(dynamic.int(1), atom.decoder())
33+
== Error([decode.DecodeError("Atom", "Int", [])])
34+
}

0 commit comments

Comments
 (0)