View Source Construct.Type behaviour (Construct v3.0.1)

Type-coercion module, originally copied and modified from Ecto.Type and behaviour to implement your own types.

defining-custom-types

Defining custom types

defmodule CustomType do
  @behaviour Construct.Type

  def cast(value) do
    {:ok, value}
  end
end

Link to this section Summary

Callbacks

Casts the given input to the custom type.

Functions

Behaves like cast/3, but without options provided to nested types.

Casts a value to the given type.

Checks if we have a primitive type.

Link to this section Types

@type builtin() ::
  :integer
  | :float
  | :boolean
  | :string
  | :binary
  | :pid
  | :reference
  | :decimal
  | :utc_datetime
  | :naive_datetime
  | :date
  | :time
  | :any
  | :array
  | {:array, t()}
  | :map
  | {:map, t()}
  | :struct
@type cast_ret() :: {:ok, term()} | {:error, term()} | :error
@type custom() :: module() | Construct.t()
@type t() :: builtin() | custom() | [builtin() | custom()]

Link to this section Callbacks

@callback cast(term()) :: cast_ret()

Casts the given input to the custom type.

Link to this section Functions

@spec cast(t(), term()) :: cast_ret() | any()

Behaves like cast/3, but without options provided to nested types.

@spec cast(t(), term(), options) :: cast_ret() | any() when options: Keyword.t()

Casts a value to the given type.

iex> cast(:any, "whatever")
{:ok, "whatever"}

iex> cast(:any, nil)
{:ok, nil}
iex> cast(:string, nil)
:error

iex> cast(:integer, 1)
{:ok, 1}
iex> cast(:integer, "1")
{:ok, 1}
iex> cast(:integer, "1.0")
:error

iex> cast(:float, 1.0)
{:ok, 1.0}
iex> cast(:float, 1)
{:ok, 1.0}
iex> cast(:float, "1")
{:ok, 1.0}
iex> cast(:float, "1.0")
{:ok, 1.0}
iex> cast(:float, "1-foo")
:error

iex> cast(:boolean, true)
{:ok, true}
iex> cast(:boolean, false)
{:ok, false}
iex> cast(:boolean, "1")
{:ok, true}
iex> cast(:boolean, "0")
{:ok, false}
iex> cast(:boolean, "whatever")
:error

iex> cast(:string, "beef")
{:ok, "beef"}
iex> cast(:binary, "beef")
{:ok, "beef"}

iex> cast(:decimal, Decimal.from_float(1.0))
{:ok, Decimal.from_float(1.0)}
iex> cast(:decimal, Decimal.new("1.0"))
{:ok, Decimal.from_float(1.0)}
iex> cast(:decimal, 1.0)
{:ok, Decimal.from_float(1.0)}
iex> cast(:decimal, "1.0")
{:ok, Decimal.from_float(1.0)}

iex> cast({:array, :integer}, [1, 2, 3])
{:ok, [1, 2, 3]}
iex> cast({:array, :integer}, ["1", "2", "3"])
{:ok, [1, 2, 3]}
iex> cast({:array, :string}, [1, 2, 3])
:error
iex> cast(:string, [1, 2, 3])
:error

iex> cast({Construct.Types.Enum, [:a, :b, :c]}, :a)
{:ok, :a}
iex> cast({Construct.Types.Enum, [:a, :b, :c]}, :d)
{:error, passed_value: :d, valid_values: [:a, :b, :c]}
@spec primitive?(t()) :: boolean()

Checks if we have a primitive type.

iex> primitive?(:string)
true
iex> primitive?(Another)
false

iex> primitive?({:array, :string})
true
iex> primitive?({:array, Another})
true

iex> primitive?([Another, {:array, :integer}])
false