View Source TypedStructor (TypedStructor v0.2.0)
TypedStructor is a library for defining structs with types effortlessly.
(This library is a rewritten version of TypedStruct because it is no longer actively maintained.)
Installation
Add :typed_structor to the list of dependencies in mix.exs:
def deps do
[
{:typed_structor, "~> 0.1"}
]
endAdd :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
endThis 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()
}
endCheck 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
endThis 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
}
endType 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
endbecomes:
defmodule User do
@type t(id, name) :: %__MODULE__{
id: id | nil,
name: name | nil,
age: non_neg_integer() | nil
}
defstruct [:id, :name, :age]
endIf 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
endYou 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
endDocumentation
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()
endYou can also document submodules this way:
typedstructor 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()
endPlugins
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/2.
You can override the options set by typed_structor/2 by passing options.
Defines a type parameter in a typed_structor/2.
Registers a plugin for the currently defined struct.
Defines a struct with type information.
Functions
Defines a field in a typed_structor/2.
You can override the options set by typed_structor/2 by passing options.
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 totrue, enforces the field, and makes its type non-nullable if:defaultis not set
How
:defaultand:enforceaffecttypeand@enforce_keys
:default:enforcetype@enforce_keyssettruet()excludedsetfalset()excludedunsettruet()includedunsetfalset() | nilexcluded
Defines a type parameter in a typed_structor/2.
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()
endFor 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, a new submodule will be created with the struct.:enforce- iftrue, the struct will enforce the keys, seefield/3options for more information.:define_struct- iffalse, the type will be defined, but the struct will not be defined. Defaults totrue.:type_kind- the kind of type to use for the struct. Defaults totype, can beopaqueortypep.: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
endCreates the struct in a submodule instead:
defmodule MyStruct do
use TypedStructor
typed_structor module: Struct do
field :name, String.t()
field :age, integer()
end
endTo 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