Domo.precond

You're seeing just the macro precond, go back to Domo module for more information.
Link to this macro

precond(type_fun)

View Source (macro)

Defines a precondition function for a field's type or the struct's type.

The type_fun argument is one element [type: fun] keyword list where type is the name of the type defined with the @type attribute and fun is a single argument user-defined precondition function.

The precondition function validates the value of the given type to match a specific format or to fulfil a set of invariants for the field's type or struct's type respectfully.

The macro should be called with a type in the same module where the @type definition is located. If that is no fulfilled, f.e., when the previously defined type has been renamed, the macro raises an ArgumentError.

defstruct [id: "I-000", amount: 0, limit: 15]

@type id :: String.t()
precond id: &validate_id/1

defp validate_id(id), do: match?(<<"I-", _::8*3>>, id)

@type t :: %__MODULE__{id: id(), amount: integer(), limit: integer()}
precond t: &validate_invariants/1

defp validate_invariants(s) do
  cond do
    s.amount >= s.limit ->
      {:error, "Amount #{s.amount} should be less then limit #{s.limit}."}

    true ->
      :ok
  end
end

TypeEnsurer module generated by Domo calls the precondition function with value of the valid type. Precondition function should return the following values: true | false | :ok | {:error, any()}.

In case of true or :ok return values TypeEnsurer finishes the validation of the field with ok. For the false return value, the TypeEnsurer generates an error message referencing the failed precondition function. And for the {:error, message} return value, it passes the message as one of the errors for the field value. message can be of any shape.

Macro adds the __precond__/2 function to the current module that routes a call to the user-defined function. The added function should be called only by Domo modules.

Attaching a precondition function to the type via this macro can be helpful to keep the same level of consistency across the domains modelled with structs sharing the given type.