defmodule Irc.User do require Record @moduledoc """ Represents an IRC user. Not all field may be returned in events. Its main structure is the struct `t()`, but the record `irc_user()` can be used to write queries against an ets collection. """ @record :irc_user @attrs [ :id, :owner, :nick, :user, :host, :name, :account, :server, :idle, :away, :connected_at, {:operator, false}, {:modes, []}, {:chanmodes, %{}}, {:channels, []}, {:assigns, %{}}, {:private, %{persisted: false}}, ] defstruct @attrs record_attrs = Enum.map(@attrs, fn ({_,_}=kv) -> kv (k) -> {k, :undefined} end) keys = :lists.map(&elem(&1, 0), record_attrs) vals = :lists.map(&{&1, [], nil}, keys) pairs = :lists.zip(keys, vals) Record.defrecord(@record, record_attrs) # @type t :: %__MODULE__{ # id: String.t(), # owner: nil | pid(), # nick: String.t(), # user: nil | String.t(), # host: nil | String.t(), # name: nil | String.t(), # account: nil | String.t(), # server: nil | String.t(), # idle: nil | {non_neg_integer(), NaiveDateTime.t()}, # operator: boolean(), # modes: [], # channels: [], # chanmodes: %{String.t() => String.t()}, ## assigns: %{any() => any()} # } # @type record :: record(:irc_user) @doc false def __attrs__, do: @attrs # @spec to_record(t()) :: t() def to_record(%__MODULE__{unquote_splicing(pairs)}) do {@record, unquote_splicing(vals)} end # @spec from_record(t()) :: t() def from_record({@record, unquote_splicing(vals)}) do %__MODULE__{unquote_splicing(pairs)} end # @spec from_mask(IRC.Mask.t()) :: t() def from_mask(%Irc.Mask{user: user, nick: nick, host: host}) when is_binary(nick) do %__MODULE__{nick: nick, user: user, host: host} end # @spec to_mask(t()) :: IRC.Mask.t() def to_mask(%__MODULE__{nick: nick, user: user, host: host}) do Irc.Mask.new(nick, user, host) end defimpl Irc.Addressable, for: __MODULE__ do def nick(%{nick: nick}), do: nick def user(%{user: user}), do: user def host(%{host: host}), do: host end end