@@ -35,6 +35,7 @@ defmodule TypedStruct do
3535 individual fields.
3636 * `opaque` - if set to true, creates an opaque type for the struct.
3737 * `module` - if set, creates the struct in a submodule named `module`.
38+ * `parameters` - if set, adds these parameters to the generated `t()`.
3839
3940 ## Examples
4041
@@ -74,6 +75,42 @@ defmodule TypedStruct do
7475 field :field_four, atom(), default: :hey
7576 end
7677 end
78+
79+ You can also add type parameters:
80+
81+ defmodule RepairOrder do
82+ use TypedStruct
83+
84+ @type new :: %{status: :new}
85+ @type in_progress :: %{status: :in_progress, progress: integer()}
86+ @type completed :: %{status: :completed}
87+
88+ typedstruct parameters: [state] do
89+ field :state, state()
90+ customer: String.t()
91+ end
92+
93+ @spec new(String.t()) :: t(new())
94+ def new(customer) do
95+ %{state: %{status: :new}, customer: customer}
96+ end
97+
98+ @spec start_repair(t(new())) :: t(in_progress())
99+ def start_repair(order) do
100+ put_in(order.state, %{status: :in_progress, progress: 0})
101+ end
102+
103+ @spec advance_repair(t(in_progress()), integer()) :: t(in_progress())
104+ def advance_repair(order, progress) do
105+ put_in(order.state.progress, progress)
106+ end
107+
108+ @spec finish_repair(t(in_progress())) :: t(completed())
109+ def finish_repair(order) do
110+ put_in(order.state, %{status: :completed})
111+ end
112+ end
113+
77114 """
78115 defmacro typedstruct ( opts \\ [ ] , do: block ) do
79116 ast = TypedStruct . __typedstruct__ ( block , opts )
@@ -116,13 +153,19 @@ defmodule TypedStruct do
116153
117154 @ doc false
118155 defmacro __type__ ( types , opts ) do
156+ type_parameters = Keyword . get ( opts , :parameters , [ ] )
157+
119158 if Keyword . get ( opts , :opaque , false ) do
120- quote bind_quoted: [ types: types ] do
121- @ opaque t ( ) :: % __MODULE__ { unquote_splicing ( types ) }
159+ quote bind_quoted: [ types: types , type_parameters: type_parameters ] do
160+ @ opaque t ( unquote_splicing ( type_parameters ) ) :: % __MODULE__ {
161+ unquote_splicing ( types )
162+ }
122163 end
123164 else
124- quote bind_quoted: [ types: types ] do
125- @ type t ( ) :: % __MODULE__ { unquote_splicing ( types ) }
165+ quote bind_quoted: [ types: types , type_parameters: type_parameters ] do
166+ @ type t ( unquote_splicing ( type_parameters ) ) :: % __MODULE__ {
167+ unquote_splicing ( types )
168+ }
126169 end
127170 end
128171 end
0 commit comments