etf_js

Gleam bindings for erlang-etf.js. This library lets you convert erlang ETF encoded terms into (reasonable) JavaScript equivalents.

Installation

For compression support, promises are required. If compression will not be used, then you don’t need gleam_javascript.

gleam add etf_js gleam_javascript

Furthermore, the NPM package pako must be installed if DecompressionStream or node:zlib is not available in the JS runtime.

Examples

Please see the tests/ directory for usage examples.

A simple example would be:

import etf_js
import gleam/decode
import gleam/javascript/promise

pub fn main() {
  // to get this binary, write this in the Erlang shell:
  // `term_to_binary(<<"Hello, world!"/utf8>>).`
  let bits = <<131,109,0,0,0,13,72,101,108,108,111,44,32,119,111,114,
  108,100,33>>

  // since ETF binaries can be compressed, promises are required
  // to parse them. However, if you know for a fact that a certain
  // binary isn't compressed (hint: the second byte must *not* be 80),
  // then you can call this method, which is synchronous
  let assert Ok(term) = etf_js.to_dynamic_no_compression(bits)

  // term is a dynamic, so we need to decode it
  // Gleam's Erlang target represents strings as UTF-8 bitarrays, since
  // Erlang does not have a standalone string type, but JS does, so we
  // can't use decode.string here, since that only checks for JS strings,
  // and not UTF-8 bitarrays. The `lossy_string` decoder checks for both.
  let assert Ok("Hello, world!") = decode.run(etf_js.lossy_string())

  // You may also use the etf_js.decode[_no_compression] methods to parse
  // and decode the ETF binary in one function call!

  // Compression! This is a list of a thousand ones!
  // to get this binary, run:
  // `term_to_binary([1 || _ <- lists:seq(1, 1000)], [compressed])`
  // in the Erlang shell.
  let bits = <<131,80,0,0,3,235,120,156,203,102,126,193,56,10,70,193,
  40,24,246,0,0,225,210,5,63>>
  use res <- promise.await(etf_js.to_dynamic(bits))
  let assert Ok(term) = res
  let assert Ok(list) = decode.run(res, decode.list(decode.string))
  // list will have one thousand ones!
  promise.resolve(Nil)
}
Search Document