Current section

Files

Jump to
altstd_compact lib altstd compact.ex
Raw

lib/altstd/compact.ex

defprotocol Altstd.Compact do
@moduledoc ~S"""
### Deriving
defmodule Valuable do
@derive [{Altstd.Compact, keys: [:price, :tax]}]
defstruct [
id: nil,
price: 0,
tax: 0,
]
end
### Custom implementation
defmodule Valuable do
defstruct [
id: nil,
price: 0,
tax: 0,
]
end
defimpl Altstd.Compact, for: Valuable do
def resolve(object, _opts \\ []) do
case object.price + object.tax do
0 ->
{:reject, object}
_any ->
{:resolve, object}
end
end
def cast(object, opts \\ []) do
resolution =
object
|> Altstd.Compact.resolve(opts)
case resolution do
{:resolve, resolved_value} ->
resolved_value
|> List.wrap()
{:reject, _any} ->
[]
:reject ->
[]
resolved_value ->
resolved_value
|> List.wrap()
end
end
end
"""
@moduledoc since: "0.1.0"
@doc since: "0.1.0"
@type t :: list(any())
@doc since: "0.1.0"
@type resolution_t :: {:resolve, any()} | any() | {:reject, any()} | :reject
@fallback_to_any true
@doc ~S"""
Should reject `object` if it's a falsey value.
Otherwise, it should resolve the `object`.
The values are falsey:
- `nil`
- `false`
- `:error`
- `:reject`
- `0`
- `''`
- `""`
- `[]`
- `{}`
- `%{}`
- `PID`s that are not alive
- `Port`s that are closed
- `Tuple`s whose first elements are falsey values
## Examples
iex> Altstd.Compact.resolve(0)
{:reject, 0}
iex> Altstd.Compact.resolve(nil)
{:reject, nil}
iex> Altstd.Compact.resolve(true)
{:resolve, true}
"""
@doc since: "0.1.0"
@spec resolve(any(), keyword) :: Altstd.Compact.resolution_t()
def resolve(object, opts \\ [])
@doc ~S"""
Should remove all falsey values in the given `object` recursively.
If `object` is not an instance of list, it must be simply
wrapped by an empty list after resolution succeed.
If `object` gets rejected while resolving, the function should
return an empty list.
## Examples
iex> Altstd.Compact.cast([0, 1, false, 2, '', 3])
[1, 2, 3]
iex> Altstd.Compact.cast(true)
[true]
iex> Altstd.Compact.cast(nil)
[]
"""
@doc since: "0.1.0"
@spec cast(any(), keyword) :: Altstd.Compact.t()
def cast(object, opts \\ [])
end