diff options
Diffstat (limited to 'lib/irc/line.ex')
-rw-r--r-- | lib/irc/line.ex | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/irc/line.ex b/lib/irc/line.ex new file mode 100644 index 0000000..56836a8 --- /dev/null +++ b/lib/irc/line.ex @@ -0,0 +1,69 @@ +defmodule Irc.Line do + @type t :: %__MODULE__{ + tags: Map.t(), + source: Irc.Mask.t() | String.t() | nil, + command: String.t(), + args: list() + } + defstruct __private__: %{}, tags: %{}, source: nil, command: nil, args: [] + + def new(command) do + new(command, []) + end + + def new(command, args) do + new(command, args, %{}) + end + + def new(command, arg, tags) when not is_list(arg) do + new(command, [arg], tags) + end + + def new(command, args, tags) do + %__MODULE__{command: command, args: args, tags: tags, __private__: %{at: DateTime.utc_now()}} + end + + @doc "Returns the line date (server time if sent, otherwise, parse time)" + @spec at(t()) :: DateTime.t() + def at(%__MODULE__{__private__: %{at: at}, tags: %{"time" => server_time}}) do + case DateTime.from_iso8601(server_time) do + {:ok, date} -> date + _ -> at + end + end + def at(%__MODULE__{__private__: %{at: at}}), do: at + def at(_), do: nil + + @spec to?(t(), Irc.Addressable.t()) :: boolean + @doc "Returns true if the line is adressed to the connection." + def to?(%__MODULE__{args: [nick | _]}, addressable) do + Irc.Addressable.nick(addressable) == nick + end + + @spec self?(t(), Irc.Addressable.t()) :: boolean + @doc "Returns true if the line source is the from the given connection/mask." + def self?(%__MODULE__{source: nick}, addressable) when is_binary(nick) do + Irc.Addressable.nick(addressable) == nick + end + def self?(%__MODULE__{source: source_addressable}, addressable) do + Irc.Addressable.equal?(source_addressable, addressable) + end + + defimpl String.Chars, for: __MODULE__ do + def to_string(line) do + Irc.Parser.Line.encode(line) + end + end + + defimpl Inspect, for: __MODULE__ do + @moduledoc false + import Inspect.Algebra + + def inspect(struct, _opts) do + tags = Enum.map(struct.tags, fn({k, v}) -> concat([k, "=", v]) end) |> Enum.join(",") + Enum.join(["#IRC.Line<", struct.source, " ", struct.command, " ", inspect(struct.args), " (", tags, ")>"], "") + end + end + + +end |