View Source Ion (Ion v0.1.0)

Lightweight utility library for efficient IO data and chardata handling.

Why Ion?

See README.

Examples

IO data and chardata can be easily be built using:

a. interpolation with the ~i sigil:

  iex> import Ion, only: :sigils
  iex> ~i"atom: #{:foo}, number: #{12 + 2.35}\n"
  ["atom: ", "foo", ", number: ", "14.35", 10]

b. joining using join/2 or map_join/3:

  iex> Ion.join(100..103, ",")
  [[["100", "," | "101"], "," | "102"], "," | "103"]

  iex> Ion.map_join(1..4, ",", & &1 + 100)
  [[["101", "," | "102"], "," | "103"], "," | "104"]

Summary

Functions

Returns true if iodata_or_chardata is empty.

Joins the given enumerable into IO data or chardata using joiner as separator.

Maps and joins the given enumerable as IO data or chardata, in one pass.

A sigil to build IO data or chardata and avoid string concatenation.

Functions

Link to this function

iodata_empty?(iodata_or_chardata)

View Source
@spec iodata_empty?(iodata() | IO.chardata()) :: boolean()

Returns true if iodata_or_chardata is empty.

Unlike IO.iodata_length(iodata) == 0 which needs to walk the complete tree, it will bail early as soon as it finds at least one byte or codepoint.

It should be constant time for most typical outputs, with the exception of atypical cases where the head is a deep nested tree.

Even if IO.iodata_length/1 is a very efficient BIF implemented in C, it has a linear algorithmic complexity and can become slow on bigger trees.

Examples

iex> Ion.iodata_empty?(["", []])
true
iex> Ion.iodata_empty?('a')
false
iex> Ion.iodata_empty?(["a"])
false
iex> Ion.iodata_empty?(["", [], ["" | "c"]])
false
Link to this function

join(enumerable, joiner \\ "")

View Source
@spec join(Enumerable.t(data | String.Chars.t()), binary()) :: data
when data: iodata() | IO.chardata()

Joins the given enumerable into IO data or chardata using joiner as separator.

It is a fast equivalent to Enum.join/2.

Examples

iex> iodata = Ion.join(1..3)
iex> IO.iodata_to_binary(iodata)
"123"

iex> iodata = Ion.join(1..3, " + ")
iex> IO.iodata_to_binary(iodata)
"1 + 2 + 3"
Link to this function

map_join(enumerable, joiner \\ "", mapper)

View Source
@spec map_join(Enumerable.t(element), binary(), (element -> data | String.Chars.t())) ::
  data
when data: iodata() | IO.chardata(), element: term()

Maps and joins the given enumerable as IO data or chardata, in one pass.

It is a fast equivalent to Enum.map_join/3.

Examples

iex> iodata = Ion.map_join(1..3, &(&1 * 2))
iex> IO.iodata_to_binary(iodata)
"246"

iex> iodata = Ion.map_join(1..3, " + ", &(&1 * 2))
iex> IO.iodata_to_binary(iodata)
"2 + 4 + 6"
Link to this macro

sigil_i(term, modifiers)

View Source (macro)

A sigil to build IO data or chardata and avoid string concatenation.

Use import Ion to use it, or import Ion, only: :sigils.

This sigil provides a faster version of string interpolation which:

  • will build a list with all chunks instead of concatenating them as a string
  • will keep interpolated lists and binaries untouched, without any validation or transformation
  • will cast anything else using to_string/1

Works with both IO data and Chardata. See their respective documentation or this guide for more information.

Examples

iex> ~i"atom: #{:foo}, number: #{12 + 2.35}\n"
["atom: ", "foo", ", number: ", "14.35", 10]

The data produced corresponds to the binary that a regular string interpolation would have produced:

iex> IO.iodata_to_binary(~i"atom: #{:foo}, number: #{12 + 2.35}\n")
"atom: foo, number: 14.35\n"
iex> "atom: #{:foo}, number: #{12 + 2.35}\n"
"atom: foo, number: 14.35\n"

Can be used to build chardata too:

iex> chardata = ~i"charlist: #{~c(ジョルノ)}!"
["charlist: ", [12472, 12519, 12523, 12494], 33]
iex> IO.chardata_to_string(chardata)
"charlist: ジョルノ!"