View Source Pathex (Pathex v2.2.0)
This module contains functions and macros to be used with Pathex
and i
To use Pathex just insert to your context. You can import Pathex in module body or even in function body.
require Pathex
import Pathex, only: [path: 1, path: 2, "~>": 2, ...]
Or you can use use
defmodule MyModule do
# `default_mod` option is optional
# when no mod is specified, `:naive` is selected
use Pathex, default_mod: :json
...
end
This will import all operatiors and path
macro
Any macro here belongs to one of three categories:
Link to this section Summary
Types
Function which is passed to path-closure as second element in args tuple
This depends on the modifier
Value returned by non-bang path call
Also known as path-closure
Also known as path-closure
Functions
Creates composition of two paths which has some inspiration from logical and
.
This means that a &&& b
path-closure tries to apply a
and only if it returns {:ok, something}
, tries
apply b
and if b
returns exactly the same as a
does, the a &&& b
returns {:ok, something}
Easy and convenient way to add pathex to your module.
This macro creates compositions of paths which work along with each other
Applies func
under path
in struct
and returns result of this func
.
Raises if path is not found.
Applies func
under path
in struct
and returns result of this func
.
The same as Pathex.~>/2
for those who do not like operators
Deletes value under path
in struct
or raises if value is not found.
Deletes value under path
in struct
.
Gets the value under path
in struct
or returns default value if not found.
Applies func
under path
of struct
.
Applies func
under path
of struct
.
Sets the value
under path
in struct
.
Sets the value
under path
in struct
.
Gets the value under path
in struct
or returns default
when path
is not present.
Inspect the given path-closure and returns string which corresponds to given path-closure
Applies the func
to the item under path
in struct
and returns modified structure.
Works like Map.update!/3
.
Applies func
to the item under the path
in struct
and returns modified structure. Works like Map.update!/3
but doesn't raise.
Creates path from quoted
ast. Paths look like unix fs path and consist of
elements separated from each other with /
. See
Gets value under path
in struct
and then deletes it.
Note that current implementation of this function performs double lookup.
Macro which gets value in the structure and deletes it. Note that current implementation of this function performs double lookup.
Sets the value
under path
in struct
. Think of it like Map.put/3
.
Sets value
under path
in structure
. Think of it like Map.put/3
.
Gets the value under path
in struct
. Raises if path
not found.
Gets the value under path
in struct
.
Creates composition of two paths which has some inspiration from logical or
.
This means that a ||| b
path-closure tries to apply a
and only if it returns :error
, tries
apply b
Creates composition of two paths similar to concatenating them together.
This means that a ~> b
path-closure applies a
and only if it returns {:ok, something}
it applies b
to something
Link to this section Types
@type force_update_args(input, output) :: {input, inner_func(output), any()}
Function which is passed to path-closure as second element in args tuple
@type inspect_args() :: any()
@type mod() :: :map | :json | :naive
More about modifiers
This depends on the modifier
@type result(inner) :: {:ok, inner} | :error | :delete_me
Value returned by non-bang path call
@type t() :: t(pathex_compatible_structure(), any())
Also known as path-closure
@type t(input, output) :: (op_name(), force_update_args(input, output) | update_args(input, output) | inspect_args() -> result(output | input))
Also known as path-closure
@type update_args(input, output) :: {input, inner_func(output)}
Link to this section Functions
Creates composition of two paths which has some inspiration from logical and
.
This means that a &&& b
path-closure tries to apply a
and only if it returns {:ok, something}
, tries
apply b
and if b
returns exactly the same as a
does, the a &&& b
returns {:ok, something}
Example:
iex> p1 = path :x / :y
iex> p2 = path :a / :b
iex> ap = p1 &&& p2
iex> {:ok, 1} = view %{x: %{y: 1}, a: [b: 1]}, ap
iex> :error = view %{x: %{y: 1}, a: [b: 2]}, ap
iex> {:ok, %{x: %{y: 2}, a: [b: 2]}} = set %{x: %{y: 1}, a: [b: 1]}, ap, 2
iex> {:ok, %{x: %{y: 2}, a: %{b: 2}}} = force_set %{}, ap, 2
Easy and convenient way to add pathex to your module.
You can specify modifier
use Pathex, default_mod: :json
Or just use it with default :naive
modifier
use Pathex
This macro creates compositions of paths which work along with each other
Think of alongside([path1, path2, path3])
as path1 &&& path2 &&& path3
The only difference is that for viewing alongside returns list of variables
Example:
iex> pa = alongside [path(:x), path(:y)]
iex> {:ok, [1, 2]} = view(%{x: 1, y: 2}, pa)
iex> {:ok, %{x: 3, y: 3}} = set(%{x: 1, y: 2}, pa, 3)
iex> :error = set(%{x: 1}, pa, 3)
iex> {:ok, %{x: 1, y: 1}} = force_set(%{}, pa, 1)
Applies func
under path
in struct
and returns result of this func
.
Raises if path is not found.
Example:
iex> x = 1
iex> 9 = at! [0, %{x: 8}], path(x / :x), fn x -> x + 1 end
iex> p = path "hey" / 0
iex> {:here, 9} = at!(%{"hey" => {9, -9}}, p, & {:here, &1})
Applies func
under path
in struct
and returns result of this func
.
Example:
iex> x = 1
iex> {:ok, 9} = at [0, %{x: 8}], path(x / :x), fn x -> x + 1 end
iex> p = path "hey" / 0
iex> {:ok, {:here, 9}} = at(%{"hey" => {9, -9}}, p, & {:here, &1})
The same as Pathex.~>/2
for those who do not like operators
Example:
iex> p1 = path :x / :y
iex> p2 = path :a / :b
iex> composed_path = concat(p1, p2)
iex> {:ok, 1} = view %{x: [y: [a: [a: 0, b: 1]]]}, composed_path
Deletes value under path
in struct
or raises if value is not found.
Example:
iex> x = 1
iex> [0, %{}] = delete!([0, %{x: 8}], path(x / :x))
Deletes value under path
in struct
.
Example:
iex> x = 1
iex> {:ok, [0, %{}]} = delete([0, %{x: 8}], path(x / :x))
iex> :error = delete([0, %{x: 8}], path(1 / :y))
Gets the value under path
in struct
or returns default value if not found.
Example:
iex> x = 1
iex> true = exists?([0, %{x: 8}], path(x / :x))
iex> p = path "hey" / "you"
iex> false = exists?(%{"hey" => [x: 1]}, p)
Applies func
under path
of struct
.
If the path does not exist it creates the path favouring maps when structure is unknown and inserts default value.
Example:
iex> x = 1
iex> [0, %{x: {:xxx, 8}}] = force_over!([0, %{x: 8}], path(x / :x), & {:xxx, &1}, 123)
iex> p = path "hey" / 0
iex> %{"hey" => %{0 => 1}} = force_over!(%{}, p, fn x -> x + 1 end, 1)
If the item in path doesn't have the right type, it raises.
Example:
iex> p = path "hey" / "you"
iex> force_over! %{"hey" => {1, 2}}, p, fn x -> x end, "value"
** (Pathex.Error) Type mismatch in structure
Applies func
under path
of struct
.
If the path does not exist it creates the path favouring maps when structure is unknown and inserts default value.
Example:
iex> x = 1
iex> {:ok, [0, %{x: {:xxx, 8}}]} = force_over([0, %{x: 8}], path(x / :x), & {:xxx, &1}, 123)
iex> p = path "hey" / 0
iex> {:ok, %{"hey" => %{0 => 1}}} = force_over(%{}, p, fn x -> x + 1 end, 1)
If the item in path doesn't have the right type, it returns :error
.
Example:
iex> p = path "hey" / "you"
iex> :error = force_over %{"hey" => {1, 2}}, p, fn x -> x end, "value"
Sets the value
under path
in struct
.
If the path does not exist it creates the path favouring maps when structure is unknown.
Example:
iex> x = 1
iex> [0, %{x: 123}] = force_set! [0, %{x: 8}], path(x / :x), 123
iex> p = path "hey" / 0
iex> %{"hey" => %{0 => 1}} = force_set! %{}, p, 1
If the item in path doesn't have the right type, it raises.
Example:
iex> p = path "hey" / "you"
iex> force_set! %{"hey" => {1, 2}}, p, "value"
** (Pathex.Error) Type mismatch in structure
Sets the value
under path
in struct
.
If the path does not exist it creates the path favouring maps when structure is unknown.
Example:
iex> x = 1
iex> {:ok, [0, %{x: 123}]} = force_set [0, %{x: 8}], path(x / :x), 123
iex> p = path "hey" / 0
iex> {:ok, %{"hey" => %{0 => 1}}} = force_set %{}, p, 1
If the item in path doesn't have the right type, it returns :error
.
Example:
iex> p = path "hey" / "you"
iex> :error = force_set %{"hey" => {1, 2}}, p, "value"
Gets the value under path
in struct
or returns default
when path
is not present.
Example:
iex> x = 1
iex> 8 = get([0, %{x: 8}], path(x / :x))
iex> p = path "hey" / "you"
iex> nil = get(%{"hey" => [x: 1]}, p)
iex> :default = get(%{"hey" => [x: 1]}, p, :default)
Inspect the given path-closure and returns string which corresponds to given path-closure
Example:
iex> index = 1
iex> p = path(:x) ~> path(:y / index) &&& path(-1)
iex> Pathex.inspect(p)
"path(:x) ~> path(:y / 1) &&& path(-1)"
Applies the func
to the item under path
in struct
and returns modified structure.
Works like Map.update!/3
.
Example:
iex> x = 1
iex> inc = fn x -> x + 1 end
iex> [0, %{x: 9}] = over! [0, %{x: 8}], path(x / :x), inc
iex> p = path "hey" / 0
iex> %{"hey" => [2, [2]]} = over! %{"hey" => [1, [2]]}, p, inc
Applies func
to the item under the path
in struct
and returns modified structure. Works like Map.update!/3
but doesn't raise.
Example:
iex> index = 1
iex> inc = fn x -> x + 1 end
iex> {:ok, [0, %{x: 9}]} = over [0, %{x: 8}], path(index / :x), inc
iex> p = path "hey" / 0
iex> {:ok, %{"hey" => [2, [2]]}} = over %{"hey" => [1, [2]]}, p, inc
Note: Exceptions from passed function left unhandled
iex> over(%{1 => "x"}, path(1), fn x -> x + 1 end)
** (ArithmeticError) bad argument in arithmetic expression
Creates path from quoted
ast. Paths look like unix fs path and consist of
elements separated from each other with /
. See
For example:
iex> x = 1
iex> mypath = path 1 / :atom / "string" / {"tuple?"} / x
iex> structure = [0, [atom: %{"string" => %{{"tuple?"} => %{1 => 2}}}]]
iex> {:ok, 2} = view structure, mypath
Default modifier of this path/2
is :naive
which means that
- Every variable is treated as index or key to tuple, list, map and keyword
- Every atom is treated as key to map or keyword
- Every integer is treated as index to tuple, list or key to map
- Every other data type is treated as key to map
Note:
-1
allows data to be prepended to the list
iex> x = -1
iex> p1 = path(-1)
iex> p2 = path(x)
iex> {:ok, [1, 2]} = force_set([2], p1, 1)
iex> {:ok, [1, 2]} = force_set([2], p2, 1)
Gets value under path
in struct
and then deletes it.
Note that current implementation of this function performs double lookup.
Example:
iex> {1, [2, 3]} = pop!([1, 2, 3], path(0))
Macro which gets value in the structure and deletes it. Note that current implementation of this function performs double lookup.
Example:
iex> {:ok, {1, [2, 3]}} = pop([1, 2, 3], path(0))
Sets the value
under path
in struct
. Think of it like Map.put/3
.
Example:
iex> x = 1
iex> [0, %{x: 123}] = set! [0, %{x: 8}], path(x / :x), 123
iex> p = path "hey" / 0
iex> %{"hey" => [123, [2]]} = set! %{"hey" => [1, [2]]}, p, 123
Sets value
under path
in structure
. Think of it like Map.put/3
.
Example:
iex> x = 1
iex> {:ok, [0, %{x: 123}]} = set [0, %{x: 8}], path(x / :x), 123
iex> p = path "hey" / 0
iex> {:ok, %{"hey" => [123, [2]]}} = set %{"hey" => [1, [2]]}, p, 123
Gets the value under path
in struct
. Raises if path
not found.
Example:
iex> x = 1
iex> 8 = view! [0, %{x: 8}], path(x / :x)
iex> p = path "hey" / 0
iex> 9 = view! %{"hey" => {9, -9}}, p
Gets the value under path
in struct
.
Example:
iex> x = 1
iex> {:ok, 8} = view [0, %{x: 8}], path(x / :x)
iex> p = path "hey" / 0
iex> {:ok, 9} = view %{"hey" => {9, -9}}, p
Creates composition of two paths which has some inspiration from logical or
.
This means that a ||| b
path-closure tries to apply a
and only if it returns :error
, tries
apply b
Example:
iex> p1 = path :x / :y
iex> p2 = path :a / :b
iex> op = p1 ||| p2
iex> {:ok, 1} = view %{x: %{y: 1}, a: [b: 2]}, op
iex> {:ok, 2} = view %{x: 1, a: [b: 2]}, op
iex> {:ok, %{x: %{y: 2}, a: [b: 1]}} = set %{x: %{y: 1}, a: [b: 1]}, op, 2
iex> {:ok, %{x: %{y: 2}}} = force_set %{}, op, 2
iex> {:ok, %{x: %{}, a: [b: 1]}} = force_set %{x: %{y: 1}, a: [b: 1]}, op, 2
Creates composition of two paths similar to concatenating them together.
This means that a ~> b
path-closure applies a
and only if it returns {:ok, something}
it applies b
to something
Example:
iex> p1 = path :x / :y
iex> p2 = path :a / :b
iex> composed_path = p1 ~> p2
iex> {:ok, 1} = view %{x: [y: [a: [a: 0, b: 1]]]}, composed_path