I am trying to write helper macro that will allow me to write bunch of Elixir structures without lot of boilerplate, so I have written macro:
defmodule Events do
@moduledoc false
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
defmodule unquote(module) do
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
Which can be used as follows:
defmofule Event do
import Events
defevent Foo, foo: String.t(), bar: number()
end
However I would like to add possibility to add documentation to such module via @doc
module attribute:
defmodule Events do
@moduledoc false
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
docs = Module.delete_attribute(__MODULE__, :doc)
defmodule unquote(module) do
for doc <- docs do
@moduledoc doc
end
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
However it will not work as Module.get_attribute(__MODULE__, :doc)
returns either nil
when there is no documentation or {integer(), String.t()}
if there is docstring. However it miss all tags, so writing code like:
defmofule Event do
import Events
@doc "Foo"
@doc deprecated: "Bar"
defevent Foo, foo: String.t(), bar: number()
end
Will contain only "Foo"
string without specified tags. My current workaround is using custom attribute, but this isn't prettiest solution out there as it requires non-standard parameter and defining custom module attribute (which makes me dependant on use
).
defmodule Events do
@moduledoc false
defmacro __using__(_) do
quote do
import unquote(__MODULE__), only: [defevent: 1, defevent: 2]
Module.register_attribute(__MODULE__, :eventdoc, accumulate: true)
end
end
defmacro defevent(module, fields \\ []) do
keys = Keyword.keys(fields)
quote do
docs = Module.delete_attribute(__MODULE__, :eventdoc)
defmodule unquote(module) do
for doc <- docs do
@moduledoc doc
end
@type t :: %__MODULE__{unquote_splicing(fields)}
defstruct unquote(keys)
end
end
end
end
Is there any way to get values of the current @doc
with all attributes assigned?