View Source Skema.Schema (Skema v0.2.2)

Borrow from https://github.com/ejpcmac/typed_struct/blob/main/lib/typed_struct.ex

Schema specifications: Internal presentation of a schema is just a map with field names as keys and field options as values.

Example

%{
  name: [type: :string, format: ~r/{4}/],
  age: [type: :integer, number: [min: 15, max: 50]].
  skill: [type: {:array, :string}, length: [min: 1, max: 10]]
}

I. Field type

Built-in types

A type could be any of built-in supported types:

  • boolean
  • string | binary

  • integer
  • float
  • number (integer or float)
  • date
  • time
  • datetime | utc_datetime: date time with time zone

  • naive_datetime: date time without time zone
  • map
  • keyword
  • {array, type} array of built-in type, all item must be the same type

Other types Custom type may be supported depends on module.

Nested types Nested types could be a another schema or list of schema

%{
  user: [type: %{
      name: [type: :string]
    }]
}

Or list of schema

%{
  users: [type: {:array, %{
      name: [type: :string]
    }} ]
}

II. Field casting and default value

These specifications is used for casting data with Skema.Params.cast

1. Default value

Is used when the given field is missing or nil.

  • Default could be a value

    %{
      status: [type: :string, default: "active"]
    }
  • Or a function/0, this function will be invoke each time data is casted

    %{
      published_at: [type: :datetime, default: &DateTime.utc_now/0]
    }

2. Custom cast function

You can provide a function to cast field value instead of using default casting function by using cast_func: <function/1>

%{
    published_at: [type: :datetime, cast_func: &DateTime.from_iso8601/1]
}

III. Field validation

These validation are supported by valdi

Custom validation function

You can provide a function to validate the value.

Define validation: func: <function>

Function must be follow this signature

@spec func(value::any()) :: :ok | {:error, message::String.t()}

Define schema with defschema macro

defschema helps you define schema clearly and easy to use.

defmodule MyStruct do
  use Skema.Schema

  defschema do
    field :field_one, :string
    field :field_two, :integer, required: true
    field :field_four, :atom, default: :hey
    field :update_time, :naive_datetime, default: &NaiveDateTime.utc_now/0
  end
end

Summary

Functions

Defines a typed struct.

Defines a field in a typed struct.

Functions

Link to this macro

defschema(module \\ nil, list)

View Source (macro)

Defines a typed struct.

Inside a defschema block, each field is defined through the field/2 macro.

Examples

defmodule MyStruct do
  use Skema.Schema

  defschema do
    field :field_one, :string
    field :field_three, :boolean, required: true
    field :field_four, :atom, default: :hey
    field :update_time, :naive_datetime, default: &NaiveDateTime.utc_now/0
  end
end

You can create the struct in a submodule instead:

defmodule MyModule do
  use Skema.Schema

  defschema Comment do
    field :user_id, :integer, required: true
    field :content, :string, required: true
  end

  defschema Post do
    field :field_one, :string
    field :field_two, :integer, required: true
    field :field_three, :boolean, required: true
    field :field_four, :string, default: "hello"
    field :update_time, :naive_datetime, default: &NaiveDateTime.utc_now/0
    field :comment, Comment, required: true
  end
end

MyModule.Post.cast(%{field_two: 1, field_three: true, comment: %{user_id: 1, content: "hello"}})
Link to this macro

field(name, type, opts \\ [])

View Source (macro)

Defines a field in a typed struct.

Example

# A field named :example of type String.t()
field :example, String.t()

Options

  • default - sets the default value for the field
  • required - if set to true, enforces the field and makes its type non-nullable