Current section

Files

Jump to
tipo lib tipo.ex
Raw

lib/tipo.ex

defmodule Tipo do
@doc """
Returns an item indicating the type of the given value
## Examples
iex> Tipo.typeof(34)
:number
iex> Tipo.typeof(self())
:pid
"""
def typeof(value) do
typeof_atom(value)
end
# boolean type checkers
def nil?(v), do: is_nil(v)
def number?(v), do: is_number(v)
def integer?(v), do: is_integer(v)
def float?(v), do: is_float(v)
def bitstring?(v), do: is_bitstring(v)
def atom?(v), do: is_atom(v)
def function?(v), do: is_function(v)
def boolean?(v), do: is_boolean(v)
def binary?(v), do: is_binary(v)
def list?(v), do: is_list(v)
def map?(v), do: is_map(v)
def tuple?(v), do: is_tuple(v)
def pid?(v), do: is_pid(v)
def port?(v), do: is_port(v)
def reference?(v), do: is_reference(v)
# keywords: lists of two element tuples of the form {atom(), any()}
def keyword?(v), do: Keyword.keyword?(v)
def regex?(v)
def regex?(%Regex{}), do: true
def regex?(_), do: false
def module?(v) do
try do
:erlang.get_module_info(v)
true
rescue
ArgumentError -> false
end
end
def struct?(v) do
if is_map(v) do
ret = try do
v.__struct__ # attempt to access hidden key
true
rescue KeyError -> false
end
ret
else
false
end
end
# valid or printable binaries are `strings
def string?(v) do
is_binary(v) and (String.printable?(v) or String.valid?(v))
end
defp typeof_atom(v) do
cond do
is_nil(v) -> nil
is_number(v) -> :number
regex?(v) -> :regex # must come before atom
module?(v) -> :module
is_boolean(v) -> :boolean # must come before atom b/c booleans are atoms
is_atom(v) -> :atom
string?(v) -> :string
is_binary(v) -> :binary
is_bitstring(v) -> :bitstring
is_function(v) -> :function
keyword?(v) -> :keyword # must come before tuple and list, catches all tuples that match the keyword spec
is_list(v) -> :list
is_tuple(v) -> :tuple
struct?(v) -> :struct
is_map(v) -> :map
is_pid(v) -> :pid
is_port(v) -> :port
is_reference(v) -> :reference
true -> :non_primitive
end
end
end