Extructure is a flexible destructure library for Elixir.
By default the library is using loose (flexible) matching, allowing for implicit structural conversions (maps, lists and tuples, from one to another). Tuple and list key pair element order are also taken loosely by default.
Toggling from loose to Elixir-default ("rigid") mode is done via the ^
operator.
Optional variables are also supported with or without a default value.
def deps do
[
{ :extructure, "~> 0.1.0"}
]
end
The docs can be found at HexDocs.
Assuming a map of socket assigns, a standard pattern matching followed by retrieving an optional value as shown below:
%{
first_name: fist_name,
last_name: last_name,
} = socket.assigns
age = socket.assigns[ :age]
is a one-liner in Extructure:
%{ first_name, last_name, _age} <~ socket.assigns
Given the Extructure's loose treatment of structures in terms of their interchangeability, the former can be expressed in a more readable manner:
{ first_name, last_name, _age} <~ socket.assigns
or
[ first_name, last_name, _age] <~ socket.assigns
An optional variable can be written as a function taking zero or one arguments, with a single argument being the default
value, and/or as the variable name prefixed with a single underscore character _
.
[ first_name, last_name, age( 25)] <~ socket.assigns
or
[ first_name, last_name, _age( 25)] <~ socket.assigns
[ b, a] <~ [ a: 1, b: 2, c: 3]
# => [ b: 2, a: 1]
{ b, a} <~ { { :a, 1}, { :b, 2}, { :c, 3}}
# => { { :b, 2}, { :a, 1}}
The rigid approach is useful to ensure the Elixir-like matching of the right side, and necessary if deconstructing standard Elixir tuples.
^{ a, b, c} <~ { 1, 2, 3}
# ok
^{ b, a} <~ { { :a, 1}, { :b, 2}, { :c, 3}}
# error
^[ b, a] <~ [ a: 1, b: 2, c: 3]
# error
^%{ a} <~ %{ a: 1, b: 2}
# ok
Any level of nesting is supported, and with the ^
operator toggling from loose to rigid and vice versa, any matching
combination can be achieved.
Ex from the extructure_test.ex
:
%{ a, b: b = ^{ c, d, ^%{ e}}} <~ [ a: 1, b: { 3, 4, [ e: 5]}]
assert a == 1
assert b == { 3, 4, %{ e: 5}}
assert c == 3
assert d == 4
assert e == 5