Current section
Files
Jump to
Current section
Files
lib/presence.ex
defprotocol Presence do
@moduledoc ~S"""
The `Presence` protocol is responsible for
checking the presence of a value.
The functions required to be implemented are
`is_blank/1`, `is_present/1` and `presence/1`.
These functions are not automatically imported
by `Kernel`.
Currently, these modules implements `Presence` protocol.
- `Atom`
- `BitString`
- `List`
- `Map`
- `Tuple`
"""
@doc ~S"""
A value is blank if it's nil, false, empty, or a whitespace string.
For example
- `nil`
- `false`
- `[]`
- `%{}`
- `{}`
- `''`
- `' '`
are all blank.
This simplifies
!address || Enum.empty?(address)
to
is_blank(address)
## Examples
### Atom
`nil` is blank:
iex> is_blank(nil)
true
`false` is blank:
iex> is_blank(false)
true
`:false` atom is blank:
iex> is_blank(:false)
true
### List
`[]` is blank:
iex> is_blank([])
true
`' '` is blank:
iex> is_blank(' ')
true
### Map
`%{}` is blank:
iex> is_blank(%{})
true
### String
A string is blank if it's empty or contains whitespaces only:
iex> is_blank("")
true
iex> is_blank(" ")
true
iex> is_blank("\t\n\r")
true
iex> is_blank(" blah ")
false
Unicode whitespace is supported:
iex> is_blank("\u00a0")
true
### Tuple
`{}` is blank:
iex> is_blank({})
true
"""
def is_blank(value)
@doc ~S"""
A value is present if it's not blank.
"""
def is_present(value)
@doc ~S"""
Returns the `value` if it's present otherwise returns `nil`.
presence(value)
is equivalent to
is_present(value) ? value : nil
For example, something like
if is_present(state), do: state = state
if is_present(country), do: country = country
region = state || country || 'US'
becomes
region = presence(state) || presence(country) || 'US'
"""
def presence(value)
end
defimpl Presence, for: Atom do
def is_blank(atom) do
cond do
is_nil(atom) -> true
is_boolean(atom) -> atom == false
is_atom(atom) -> atom == false
end
end
def is_present(atom), do: !is_blank(atom)
def presence(atom) do
if is_present(atom), do: atom, else: nil
end
end
defimpl Presence, for: BitString do
def is_blank(string) do
String.strip(string) == ""
end
def is_present(string), do: !is_blank(string)
def presence(string) do
if is_present(string), do: string, else: nil
end
end
defimpl Presence, for: List do
def is_blank(charlist) do
charlist = charlist
|> to_string
|> String.replace(" ", "")
byte_size(charlist) == 0
end
def is_present(charlist), do: !is_blank(charlist)
def presence(charlist) do
if is_present(charlist), do: charlist, else: nil
end
end
defimpl Presence, for: Map do
def is_blank(map) do
keys = Map.keys(map)
length(keys) == 0
end
def is_present(map), do: !is_blank(map)
def presence(map) do
if is_present(map), do: map, else: nil
end
end
defimpl Presence, for: Tuple do
def is_blank(tuple) do
list = Tuple.to_list(tuple)
length(list) == 0
end
def is_present(tuple), do: !is_blank(tuple)
def presence(tuple) do
if is_present(tuple), do: tuple, else: nil
end
end