defmodule Amarula.Connection.GroupOps do @moduledoc """ Pure group-query builders for `Amarula.Connection`. Each function builds the `{iq, transform}` pair the group callbacks feed to `Connection.send_waiter_iq/4` — the IQ node to send and the fun that turns the reply node into the consumer result (`%Amarula.Group{}` / a list of them). No socket, no `state`: the IQ correlation + dispatch stay on `Connection`; only the request shape and reply parsing live here, testable in isolation. """ alias Amarula.Protocol.Groups.Metadata @type transform :: ({:ok, term()} | {:error, term()} -> {:ok, term()} | {:error, term()}) @doc "Query one group's metadata → `{iq, transform}` yielding `%Amarula.Group{}`." @spec metadata(String.t()) :: {term(), transform()} def metadata(group_jid) do iq = Metadata.query_iq(group_jid) transform = fn {:ok, node} -> with {:ok, meta} <- Metadata.parse(node), do: {:ok, Amarula.Group.from_metadata(meta)} {:error, node} -> {:error, node} end {iq, transform} end @doc "Query all joined groups → `{iq, transform}` yielding `[%Amarula.Group{}]`." @spec list() :: {term(), transform()} def list do iq = Metadata.query_all_iq() transform = fn {:ok, node} -> {:ok, metas} = Metadata.parse_all(node) {:ok, Enum.map(metas, &Amarula.Group.from_metadata/1)} {:error, node} -> {:error, node} end {iq, transform} end end