Iteraptor.Utils (iteraptor v1.15.0)

View Source

Helper functions to update nested terms

Summary

Functions

Safe put the value deeply into the term nesting structure. Creates all the intermediate keys if needed.

Digs the leaf value in the nested keyword / map.

Joins the array of keys into the string using delimiter.

Checks if the map/keyword looks like a normal list.

Splits the string by delimiter, possibly converting the keys to symbols.

Squeezes the nested structure merging same keys.

Gently tries to create a linked list out of input, returns input if it cannot be safely converted to the list.

Determines the type of the given term.

Functions

deep_put_in(target, key_value, opts \\ [])

@spec deep_put_in(%{} | keyword(), {list(), any()}, keyword()) :: %{} | keyword()

Safe put the value deeply into the term nesting structure. Creates all the intermediate keys if needed.

Examples:

iex> Iteraptor.Utils.deep_put_in(%{}, {~w|a b c|a, 42})
%{a: %{b: %{c: 42}}}
iex> Iteraptor.Utils.deep_put_in(%{a: %{b: %{c: 42}}}, {~w|a b d|a, :foo})
%{a: %{b: %{c: 42, d: :foo}}}
iex> Iteraptor.Utils.deep_put_in(%{a: %{b: [c: 42]}}, {~w|a b d|a, :foo})
%{a: %{b: [c: 42, d: :foo]}}
iex> Iteraptor.Utils.deep_put_in(%{a: %{b: [42]}}, {~w|a b|a, :foo})
%{a: %{b: [42, :foo]}}
iex> Iteraptor.Utils.deep_put_in(%{a: [:foo, %{b: 42}]}, {~w|a b|a, :foo})
%{a: [:foo, %{b: 42}, {:b, :foo}]}

dig(input, acc \\ [])

@spec dig(
  %{} | keyword(),
  keyword()
) :: {:ok, {list(), any()}} | {:error, any()}

Digs the leaf value in the nested keyword / map.

Examples:

iex> Iteraptor.Utils.dig(%{k1: %{k2: %{k3: :value}}})
{:ok, {[:k1, :k2, :k3], :value}}
iex> Iteraptor.Utils.dig([k1: [k2: [k3: :value]]])
{:ok, {[:k1, :k2, :k3], :value}}
iex> Iteraptor.Utils.dig([k1: :value, k2: :value])
{:error, [k1: :value, k2: :value]}
iex> Iteraptor.Utils.dig([k1: %{k2: [k3: :value]}])
{:ok, {[:k1, :k2, :k3], :value}}

dig!(input, acc \\ [])

@spec dig!(
  %{} | keyword(),
  keyword()
) :: {list(), any()} | no_return()

join(input, opts \\ [])

@spec join(
  Enum.t(),
  keyword()
) :: binary()

Joins the array of keys into the string using delimiter.

Examples:

iex> Iteraptor.Utils.join(~w|a b c d|)
"a.b.c.d"
iex> Iteraptor.Utils.join(~w|a b c d|, delimiter: "_")
"a_b_c_d"

quacks_as_list(map)

@spec quacks_as_list(%{} | keyword() | any()) :: true | false

Checks if the map/keyword looks like a normal list.

Examples:

iex> Iteraptor.Utils.quacks_as_list(%{"0" => :foo, 1 => :bar})
true
iex> Iteraptor.Utils.quacks_as_list([{:"1", :bar}, {:"0", :foo}])
true
iex> Iteraptor.Utils.quacks_as_list(%{foo: :bar})
false
iex> Iteraptor.Utils.quacks_as_list(%{"5" => :foo, "1" => :bar})
false
iex> Iteraptor.Utils.quacks_as_list(42)
false

split(input, opts \\ [])

@spec split(input :: binary(), opts :: keyword()) :: [binary() | atom()]

Splits the string by delimiter, possibly converting the keys to symbols.

Examples:

iex> Iteraptor.Utils.split("a.b.c.d", transform: :none)
["a", "b", "c", "d"]
iex> Iteraptor.Utils.split("a_b_c_d", delimiter: "_")
["a", "b", "c", "d"]
iex> Iteraptor.Utils.split("a.b.c.d", transform: :unsafe)
[:a, :b, :c, :d]
iex> Iteraptor.Utils.split("a.b.c.d", transform: :safe)
[:a, :b, :c, :d]

squeeze(input, opts \\ [])

@spec squeeze(
  %{} | keyword() | list() | Access.t(),
  keyword()
) :: %{} | keyword() | list()

Squeezes the nested structure merging same keys.

Examples:

#iex> Iteraptor.Utils.squeeze([foo: [bar: 42], foo: [baz: 3.14]])
#[foo: [bar: 42, baz: 3.14]]
iex> Iteraptor.Utils.squeeze([foo: %{bar: 42}, foo: %{baz: 3.14}])
[foo: %{bar: 42, baz: 3.14}]
iex> Iteraptor.Utils.squeeze([foo: %{bar: 42}, foo: :baz])
[foo: [%{bar: 42}, :baz]]
iex> Iteraptor.Utils.squeeze([a: [b: [c: 42]], a: [b: [d: 3.14]]])
[a: [b: [c: 42, d: 3.14]]]
iex> Iteraptor.Utils.squeeze([a: [b: [c: 42]], a: [b: %{d: 3.14}]])
[a: [b: [c: 42, d: 3.14]]]
iex> Iteraptor.Utils.squeeze([a: [b: [c: :foo]], a: [b: [c: 3.14]]])
[a: [b: [c: [:foo, 3.14]]]]
iex> Iteraptor.Utils.squeeze([a: [b: [:foo, :bar]], a: [b: [c: 3.14]]])
[a: [b: [:foo, :bar, {:c, 3.14}]]]
iex> Iteraptor.Utils.squeeze([a: [:foo, :bar], a: [b: [c: 3.14]]])
[a: [:foo, :bar, {:b, [c: 3.14]}]]

try_to_list(input)

@spec try_to_list(any()) :: list() | any()

Gently tries to create a linked list out of input, returns input if it cannot be safely converted to the list.

Examples:

iex> Iteraptor.Utils.try_to_list(%{"0" => :foo, 1 => :bar})
[:foo, :bar]
iex> Iteraptor.Utils.try_to_list([{:"1", :bar}, {:"0", :foo}])
[:foo, :bar]
iex> Iteraptor.Utils.try_to_list(%{foo: :bar})
%{foo: :bar}
iex> Iteraptor.Utils.try_to_list(%{"5" => :foo, "1" => :bar})
%{"5" => :foo, "1" => :bar}

type(input)

@spec type(%{} | keyword() | list() | any()) :: {atom(), any(), any()} | :error

Determines the type of the given term.

Examples:

iex> Iteraptor.Utils.type(%{foo: :bar})
{Map, %{foo: :bar}, %{}}
iex> Iteraptor.Utils.type([foo: :bar])
{Keyword, [foo: :bar], []}
iex> Iteraptor.Utils.type([{:foo, :bar}])
{Keyword, [{:foo, :bar}], []}
iex> Iteraptor.Utils.type(~w|foo bar|a)
{List, [:foo, :bar], []}
iex> Iteraptor.Utils.type(42)
:error