TypedStructor (TypedStructor v0.1.1)
Installation
Add :typed_structor
to the list of dependencies in mix.exs
:
def deps do
[
{:typed_structor, "~> 0.1.1"}
]
end
Add :typed_structor
to your .formatter.exs
file
[
# import the formatter rules from `:typed_structor`
import_deps: [..., :typed_structor],
inputs: [...]
]
Usage
General usage
To define a struct with types, use TypedStructor
,
and then define fields under the TypedStructor.typed_structor/2
macro,
using the TypedStructor.field/3
macro to define each field.
defmodule User do
# use TypedStructor to import the `typed_structor` macro
use TypedStructor
typed_structor do
# Define each field with the `field` macro.
field :id, pos_integer()
# set a default value
field :name, String.t(), default: "Unknown"
# enforce a field
field :age, non_neg_integer(), enforce: true
end
end
This is equivalent to:
defmodule User do
defstruct [:id, :name, :age]
@type t() :: %__MODULE__{
id: pos_integer() | nil,
# Note: The 'name' can not be nil, for it has a default value.
name: String.t(),
age: non_neg_integer()
}
end
Check TypedStructor.typed_structor/2
and TypedStructor.field/3
for more information.
Options
You can also generate an opaque
type for the struct,
even changing the type name:
defmodule User do
use TypedStructor
typed_structor type_kind: :opaque, type_name: :profile do
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer()
end
end
This is equivalent to:
defmodule User do
use TypedStructor
defstruct [:id, :name, :age]
@opaque profile() :: %__MODULE__{
id: pos_integer() | nil,
name: String.t() | nil,
age: non_neg_integer() | nil
}
end
Type parameters also can be defined:
defmodule User do
use TypedStructor
typed_structor do
parameter :id
parameter :name
field :id, id
field :name, name
field :age, non_neg_integer()
end
end
becomes:
defmodule User do
@type t(id, name) :: %__MODULE__{
id: id | nil,
name: name | nil,
age: non_neg_integer() | nil
}
defstruct [:id, :name, :age]
end
If you prefer to define a struct in a submodule, pass the module
option.
defmodule User do
use TypedStructor
# `%User.Profile{}` is generated
typed_structor module: Profile do
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer()
end
end
You can define the type only without defining the struct,
it is useful when the struct is defined by another library(like Ecto.Schema
).
defmodule User do
use Ecto.Schema
use TypedStructor
typed_structor define_struct: false do
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer(), default: 0
end
schema "users" do
field :name, :string
field :age, :integer, default: 0
end
end
Documentation
To add a @typedoc
to the struct type, just add the attribute in the typed_structor block:
typed_structor do
@typedoc "A typed user"
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer()
end
You can also document submodules this way:
typedstruct module: Profile do
@moduledoc "A user profile struct"
@typedoc "A typed user profile"
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer()
end
Plugins
TypedStructor
offers a plugin system to enhance functionality.
For details on creating a plugin, refer to the TypedStructor.Plugin
module.
Here is a example of TypedStructor.Plugins.Accessible
plugin to define Access
behavior for the struct.
defmodule User do
use TypedStructor
typed_structor do
plugin TypedStructor.Plugins.Accessible
field :id, pos_integer()
field :name, String.t()
field :age, non_neg_integer()
end
end
user = %User{id: 1, name: "Phil", age: 20}
get_in(user, [:name]) # => "Phil"
Summary
Functions
Defines a field in a typed_structor
.
Defines a type parameter in a typed_structor
.
Registers a plugin for the currently defined struct.
Defines a struct with type information.
Functions
Defines a field in a typed_structor
.
Example
# A field named :example of type String.t()
field :example, String.t()
Options
:default
- sets the default value for the field:enforce
- if set to true, enforces the field and makes its type non-nullable
Defines a type parameter in a typed_structor
.
Example
# A type parameter named int
parameter :int
fied :number, int # not int()
Registers a plugin for the currently defined struct.
Example
typed_structor do
plugin MyPlugin
field :string, String.t()
end
For more information on how to define your own plugins, please see
TypedStructor.Plugin
. To use a third-party plugin, please refer directly to
its documentation.
Defines a struct with type information.
Inside a typed_structor
block, you can define fields with the field/3
macro.
Options
:module
- if provided, the struct will be defined in the given module.:enforce
- iftrue
, the struct will enforce the keys.:define_struct
- iffalse
, the struct will not be defined. Defaults totrue
.:type_kind
- the kind of type to use for the struct. Defaults totype
, can beopaque
ortypep
.:type_name
- the name of the type to use for the struct. Defaults tot
.
Examples
defmodule MyStruct do
use TypedStructor
typed_structor do
field :name, String.t()
field :age, integer()
end
end
Creates the struct in a submodule instead:
defmodule MyStruct do
use TypedStructor
typed_structor module: Struct do
field :name, String.t()
field :age, integer()
end
end
To add a @typedoc
to the struct type and @moduledoc
to the submodule,
just add the module attribute in the typed_structor
block:
defmodule MyStruct do
use TypedStructor
typed_structor module: Struct do
@typedoc "A typed struct"
@moduledoc "A submodule"
field :name, String.t()
field :age, integer()
end
end