Skip to content

Commit

Permalink
Deprecated IO functions in favor of ion
Browse files Browse the repository at this point in the history
  • Loading branch information
sabiwara committed Apr 26, 2024
1 parent c3583d5 commit a59725b
Show file tree
Hide file tree
Showing 9 changed files with 9 additions and 285 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Dev

### Breaking changes

- Deprecate ~i sigil and Aja.IO module in favor of
[`Ion`](https://hex.pm/packages/ion)

## v0.6.4 (2024-01-03)

### Bug fixes
Expand Down
21 changes: 0 additions & 21 deletions bench/io/empty.exs

This file was deleted.

37 changes: 0 additions & 37 deletions bench/io/empty.results.txt

This file was deleted.

50 changes: 0 additions & 50 deletions bench/io/sigil_i.exs

This file was deleted.

31 changes: 0 additions & 31 deletions bench/io/sigil_i.results.txt

This file was deleted.

43 changes: 1 addition & 42 deletions lib/aja.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,7 @@ defmodule Aja do
Use `import Aja` to import everything, or import only the macros you need.
"""

@doc ~S"""
A sigil to build [IO data](https://hexdocs.pm/elixir/IO.html#module-io-data) and avoid string concatenation.
Use `import Aja` to use it, or `import Aja, only: [sigil_i: 2]`.
This sigil provides a faster version of string interpolation which:
- will build a list with all chunks instead of concatenating them as a string
- uses `Aja.IO.to_iodata/1` on interpolated values instead of `to_string/1`, which:
* will keep lists untouched, without any validation or transformation
* will cast anything else using `to_string/1`
Works with both [IO data](https://hexdocs.pm/elixir/IO.html#module-io-data) and
[Chardata](https://hexdocs.pm/elixir/IO.html?#module-chardata).
See their respective documentation for more information.
## Examples
iex> ~i"atom: #{:foo}, charlist: #{'abc'}, number: #{12 + 2.35}\n"
["atom: ", "foo", ", charlist: ", 'abc', ", number: ", "14.35", 10]
iex> ~i"abc#{['def' | "ghi"]}"
["abc", ['def' | "ghi"]]
iex> ~i"Giorno Giovanna"
"Giorno Giovanna"
IO data can often be used as is without ever generating the corresponding string.
If needed however, IO data can be cast as a string using `IO.iodata_to_binary/1`,
and chardata using `List.to_string/1`. In most cases, both should be the same:
iex> IO.iodata_to_binary(~i"atom: #{:foo}, charlist: #{'abc'}, number: #{12 + 2.35}\n")
"atom: foo, charlist: abc, number: 14.35\n"
iex> List.to_string(~i"abc#{['def' | "ghi"]}")
"abcdefghi"
Those are the exact same values returned by a regular string interpolation, without
the `~i` sigil:
iex> "atom: #{:foo}, charlist: #{'abc'}, number: #{12 + 2.35}\n"
"atom: foo, charlist: abc, number: 14.35\n"
iex> "abc#{['def' | "ghi"]}"
"abcdefghi"
"""
@deprecated "Use the :ion library instead (https://hex.pm/packages/ion)"
defmacro sigil_i(term, modifiers)

defmacro sigil_i({:<<>>, _, [piece]}, []) when is_binary(piece) do
Expand Down
60 changes: 3 additions & 57 deletions lib/io.ex
Original file line number Diff line number Diff line change
@@ -1,41 +1,7 @@
defmodule Aja.IO do
@moduledoc ~S"""
Some extra helper functions for working with IO data,
that are not in the core `IO` module.
"""
@moduledoc deprecated: "Use the :ion library instead (https://hex.pm/packages/ion)"

# TODO: Link about cowboy/mint, benchmarks with Jason
# TODO bench then inline

@doc ~S"""
Checks if IO data is empty in "constant" time.
Should only need to loop until it finds one character or binary to stop,
unlike `IO.iodata_length(iodata) == 0` which needs to perform the complete loop
to compute the length first.
## Examples
iex> Aja.IO.iodata_empty?(["", []])
true
iex> Aja.IO.iodata_empty?('a')
false
iex> Aja.IO.iodata_empty?(["a"])
false
iex> Aja.IO.iodata_empty?(["", [], ["" | "c"]])
false
## Rationale
Even if `IO.iodata_length/1` is a very efficient BIF implemented in C, it has a linear
algorithmic complexity and can become slow if invoked on an IO list with many elements.
This is not a far-fetched scenario, and a production use case can easily include
"big" IO-lists with:
- JSON encoding to IO-data of long lists / nested objects
- loops within HTML templates
"""
@deprecated "Use the :ion library instead (https://hex.pm/packages/ion)"
@spec iodata_empty?(iodata) :: boolean
def iodata_empty?(iodata)

Expand All @@ -51,27 +17,7 @@ defmodule Aja.IO do
end
end

@doc """
Converts the argument to IO data according to the `String.Chars` protocol.
Leaves lists untouched without any validation, calls `to_string/1` on everything else.
This is the function invoked in string interpolations within the [i sigil](`Aja.sigil_i/2`).
Works with both [IO data](https://hexdocs.pm/elixir/IO.html#module-io-data) and
[Chardata](https://hexdocs.pm/elixir/IO.html?#module-chardata),
depending on the type of the `data` parameter.
## Examples
iex> Aja.IO.to_iodata(:foo)
"foo"
iex> Aja.IO.to_iodata(99)
"99"
iex> Aja.IO.to_iodata(["abc", 'def' | "ghi"])
["abc", 'def' | "ghi"]
"""
@deprecated "Use the :ion library instead (https://hex.pm/packages/ion)"
@compile {:inline, to_iodata: 1}
@spec to_iodata(String.Chars.t() | iodata | IO.chardata()) :: iodata | IO.chardata()
def to_iodata(data) when is_list(data) or is_binary(data) do
Expand Down
31 changes: 0 additions & 31 deletions test/aja_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -318,36 +318,5 @@ defmodule ATest do

assert_raise FunctionClauseError, fn -> 8 = %{__vector__: {8}} |> vec_size() end
end

test "sigil_i" do
"a" = ~i"a"
"ゴゴゴ" = ~i"ゴゴゴ"
["int: ", "99", ".\n"] = ~i"int: #{99}.\n"
["atom: ", "foo", ".\n"] = ~i"atom: #{:foo}.\n"
["string: ", "bar", ".\n"] = ~i"string: #{"bar"}.\n"
["charlist: ", ~c"baz", ".\n"] = ~i"charlist: #{~c"baz"}.\n"

["iolist: ", [["abc"], ~c"def" | "ghi"], ".\n"] =
~i"iolist: #{[["abc"], ~c"def" | "ghi"]}.\n"

["assignments: ", "3", ".\n"] =
~i"assignments: #{a = 1
b = 2
a + b}.\n"

iodata = ~i"[#{for i <- 1..3, do: ~i({"name": "foo_#{i}"},)}]"

assert [
91,
[
["{\"name\": \"foo_", "1", "\"},"],
["{\"name\": \"foo_", "2", "\"},"],
["{\"name\": \"foo_", "3", "\"},"]
],
93
] = iodata

assert ~s([{"name": "foo_1"},{"name": "foo_2"},{"name": "foo_3"},]) = to_string(iodata)
end
end
end
16 changes: 0 additions & 16 deletions test/io_test.exs

This file was deleted.

0 comments on commit a59725b

Please sign in to comment.