Current section
Files
Jump to
Current section
Files
lib/nostrum/cache/channel_cache.ex
defmodule Nostrum.Cache.ChannelCache do
@moduledoc """
Cache for channels.
The ETS table name associated with the Channel Cache is `:channels`. Besides the
methods provided below you can call any other ETS methods on the table.
## Example
```elixir
info = :ets.info(:channels)
[..., heir: :none, name: :channels, size: 1, ...]
size = info[:size]
1
```
"""
alias Nostrum.Cache.GuildCache
alias Nostrum.Struct.Channel
alias Nostrum.Util
import Nostrum.Snowflake, only: [is_snowflake: 1]
@doc ~S"""
Retrieves a channel from the cache.
Internally, the ChannelCache process only stores
`t:Nostrum.Struct.Channel.dm_channel/0` references. To get channel
information, a call is made to a `Nostrum.Cache.GuildCache`.
If successful, returns `{:ok, channel}`. Otherwise, returns `{:error, reason}`
## Example
```elixir
case Nostrum.Cache.ChannelCache.get(133333333337) do
{:ok, channel} ->
"We found " <> channel.name
{:error, _reason} ->
"Donde esta"
end
```
"""
@spec get(Channel.id() | Nostrum.Struct.Message.t()) :: {:error, atom} | {:ok, Channel.t()}
def get(%Nostrum.Struct.Message{channel_id: channel_id}), do: get(channel_id)
def get(id) when is_snowflake(id) do
case lookup(id) do
{:ok, channel} -> {:ok, convert(channel)}
error -> error
end
end
@doc ~S"""
Same as `get/1`, but raises `Nostrum.Error.CacheError` in case of a failure.
"""
@spec get!(Channel.id() | Nostrum.Struct.Message.t()) :: no_return | Channel.t()
def get!(%Nostrum.Struct.Message{channel_id: channel_id}), do: get!(channel_id)
def get!(id) when is_snowflake(id), do: id |> get |> Util.bangify_find(id, __MODULE__)
@doc false
@spec create(map) :: Channel.t()
def create(channel) do
:ets.insert(:channels, {channel.id, channel})
convert(channel)
end
@doc false
@spec update(Channel.id()) :: :noop | {Channel.t(), Channel.t()}
def update(channel) do
case lookup(channel.id) do
{:ok, old_channel} ->
{convert(old_channel), convert(channel)}
_ ->
:noop
end
end
@doc false
@spec delete(Channel.id()) :: :noop | Channel.t()
def delete(id) do
case lookup(id) do
{:ok, channel} ->
:ets.delete(:channels, id)
convert(channel)
_ ->
:noop
end
end
@doc false
@spec lookup(Channel.id()) :: {:error, :channel_not_found} | {:ok, map}
def lookup(id) do
case :ets.lookup(:channels, id) do
[] ->
GuildCache.select_by([channel_id: id], fn %{channels: channels} ->
Map.get(channels, id, {:error, :channel_not_found})
end)
[{^id, channel}] ->
{:ok, channel}
end
end
@doc false
def convert(%{__struct__: _} = struct), do: struct
def convert(map), do: Channel.to_struct(map)
end