Distributed Erlang over iroh P2P + TLS, with a bot powers SDK
1//! Small helpers for building and reading Erlang terms.
2
3use erl_dist::term::{Atom, FixInteger, List, Pid, Reference, Term};
4
5/// Atom from a string.
6pub fn atom(name: impl AsRef<str>) -> Atom {
7 Atom::from(name.as_ref())
8}
9
10/// Empty list `[]`.
11pub fn nil() -> List {
12 List::nil()
13}
14
15/// Proper list from a sequence of terms.
16pub fn list(items: impl IntoIterator<Item = Term>) -> List {
17 List::from(items.into_iter().collect::<Vec<_>>())
18}
19
20/// Small integer.
21pub fn int(n: i32) -> FixInteger {
22 FixInteger::from(n)
23}
24
25/// 2-tuple `{a, b}`.
26pub fn tuple2(a: impl Into<Term>, b: impl Into<Term>) -> Term {
27 Term::from(eetf::Tuple::from(vec![a.into(), b.into()]))
28}
29
30/// 3-tuple `{a, b, c}`.
31pub fn tuple3(a: impl Into<Term>, b: impl Into<Term>, c: impl Into<Term>) -> Term {
32 Term::from(eetf::Tuple::from(vec![a.into(), b.into(), c.into()]))
33}
34
35/// 4-tuple.
36pub fn tuple4(
37 a: impl Into<Term>,
38 b: impl Into<Term>,
39 c: impl Into<Term>,
40 d: impl Into<Term>,
41) -> Term {
42 Term::from(eetf::Tuple::from(vec![a.into(), b.into(), c.into(), d.into()]))
43}
44
45/// N-tuple from a vec of terms.
46pub fn tuple(elements: Vec<Term>) -> Term {
47 Term::from(eetf::Tuple::from(elements))
48}
49
50/// Binary from bytes.
51pub fn binary(data: impl AsRef<[u8]>) -> Term {
52 Term::from(eetf::Binary::from(data.as_ref().to_vec()))
53}
54
55/// String as a char list (Erlang string).
56pub fn string(s: impl AsRef<str>) -> Term {
57 Term::from(eetf::List::from(
58 s.as_ref()
59 .chars()
60 .map(|c| Term::from(FixInteger::from(c as i32)))
61 .collect::<Vec<_>>(),
62 ))
63}
64
65/// Local pid for this node (serial 0 — the "bot process").
66pub fn local_pid(node: &str, creation: u32) -> Pid {
67 Pid::new(node.to_string(), 0, 0, creation)
68}
69
70/// Fresh distribution reference.
71pub fn make_ref(node: &str, creation: u32) -> Reference {
72 Reference {
73 node: Atom::from(node),
74 id: vec![rand::random(), rand::random(), rand::random()],
75 creation,
76 }
77}
78
79/// Try to extract an atom name.
80pub fn as_atom(term: &Term) -> Option<&str> {
81 match term {
82 Term::Atom(a) => Some(a.name.as_str()),
83 _ => None,
84 }
85}
86
87/// Pretty-print a term (debug-ish, good enough for logs).
88pub fn format_term(term: &Term) -> String {
89 format!("{term}")
90}