From d549b732e19003b8f108745e2b463491184aa135 Mon Sep 17 00:00:00 2001 From: shibao Date: Mon, 31 Jan 2022 20:10:48 -0500 Subject: [PATCH] typespec out contexts --- lib/cannery/accounts.ex | 33 +++++++------------ lib/cannery/containers.ex | 67 +++++++++++++++++++++++++++++++++------ lib/cannery/invites.ex | 56 ++++++++++++++++---------------- lib/cannery/tags.ex | 66 +++++++++++++++++++------------------- 4 files changed, 129 insertions(+), 93 deletions(-) diff --git a/lib/cannery/accounts.ex b/lib/cannery/accounts.ex index 1a1725e8..130415b2 100644 --- a/lib/cannery/accounts.ex +++ b/lib/cannery/accounts.ex @@ -23,9 +23,7 @@ defmodule Cannery.Accounts do """ @spec get_user_by_email(String.t()) :: User.t() | nil - def get_user_by_email(email) when is_binary(email) do - Repo.get_by(User, email: email) - end + def get_user_by_email(email) when is_binary(email), do: Repo.get_by(User, email: email) @doc """ Gets a user by email and password. @@ -61,13 +59,11 @@ defmodule Cannery.Accounts do ** (Ecto.NoResultsError) """ - @spec get_user!(Ecto.UUID.t()) :: User.t() + @spec get_user!(User.t()) :: User.t() def get_user!(id), do: Repo.get!(User, id) @spec list_users_by_role(atom()) :: [User.t()] - def list_users_by_role(role) do - Repo.all(from u in User, where: u.role == ^role) - end + def list_users_by_role(role), do: Repo.all(from u in User, where: u.role == ^role) @spec list_all_users(boolean()) :: [User.t()] def list_all_users(confirmed_users_only \\ true) do @@ -115,9 +111,8 @@ defmodule Cannery.Accounts do """ @spec change_user_registration(User.t() | User.new_user()) :: Changeset.t() @spec change_user_registration(User.t() | User.new_user(), map()) :: Changeset.t() - def change_user_registration(user, attrs \\ %{}) do - User.registration_changeset(user, attrs, hash_password: false) - end + def change_user_registration(user, attrs \\ %{}), + do: User.registration_changeset(user, attrs, hash_password: false) ## Settings @@ -131,9 +126,7 @@ defmodule Cannery.Accounts do """ @spec change_user_email(User.t(), map()) :: Changeset.t() - def change_user_email(user, attrs \\ %{}) do - User.email_changeset(user, attrs) - end + def change_user_email(user, attrs \\ %{}), do: User.email_changeset(user, attrs) @doc """ Returns an `%Changeset{}` for changing the user role. @@ -145,9 +138,7 @@ defmodule Cannery.Accounts do """ @spec change_user_role(User.t(), atom()) :: Changeset.t() - def change_user_role(user, role) do - User.role_changeset(user, role) - end + def change_user_role(user, role), do: User.role_changeset(user, role) @doc """ Emulates that the email will change without actually changing @@ -228,9 +219,8 @@ defmodule Cannery.Accounts do """ @spec change_user_password(User.t(), map()) :: Changeset.t() - def change_user_password(user, attrs \\ %{}) do - User.password_changeset(user, attrs, hash_password: false) - end + def change_user_password(user, attrs \\ %{}), + do: User.password_changeset(user, attrs, hash_password: false) @doc """ Updates the user password. @@ -263,9 +253,7 @@ defmodule Cannery.Accounts do end @spec delete_user!(User.t()) :: User.t() - def delete_user!(user) do - user |> Repo.delete!() - end + def delete_user!(user), do: user |> Repo.delete!() ## Session @@ -350,6 +338,7 @@ defmodule Cannery.Accounts do end end + @spec confirm_user_multi(User.t()) :: Multi.t() defp confirm_user_multi(user) do Multi.new() |> Multi.update(:user, User.confirm_changeset(user)) diff --git a/lib/cannery/containers.ex b/lib/cannery/containers.ex index 1d4ea214..8e8a390c 100644 --- a/lib/cannery/containers.ex +++ b/lib/cannery/containers.ex @@ -4,8 +4,9 @@ defmodule Cannery.Containers do """ import Ecto.Query, warn: false - alias Cannery.{Containers.Container, Repo} - alias Ecto.{Changeset, UUID} + alias Cannery.{Containers.Container, Repo, Tags.Tag} + alias Cannery.Containers.{Container, ContainerTag} + alias Ecto.{Changeset} @doc """ Returns the list of containers. @@ -16,10 +17,9 @@ defmodule Cannery.Containers do [%Container{}, ...] """ - @spec list_containers() :: [Container.t()] - def list_containers do - Repo.all(Container) - end + @spec list_containers(user_or_user_id :: User.t() | User.id()) :: [Container.t()] + def list_containers(%{id: user_id}), do: list_containers(user_id) + def list_containers(user_id), do: Repo.all(from c in Container, where: c.user_id == ^user_id) @doc """ Gets a single container. @@ -35,7 +35,7 @@ defmodule Cannery.Containers do ** (Ecto.NoResultsError) """ - @spec get_container!(container_id :: UUID.t()) :: Container.t() + @spec get_container!(Container.id()) :: Container.t() def get_container!(id), do: Repo.get!(Container, id) @doc """ @@ -67,7 +67,7 @@ defmodule Cannery.Containers do {:error, %Ecto.Changeset{}} """ - @spec update_container(Container.t() | Ecto.Changeset.t(), map()) :: + @spec update_container(Container.t() | Ecto.Changeset.t(), attrs :: map()) :: {:ok, Container.t()} | {:error, Ecto.Changeset.t()} def update_container(container, attrs) do container |> Container.changeset(attrs) |> Repo.update() @@ -101,7 +101,54 @@ defmodule Cannery.Containers do %Ecto.Changeset{data: %Container{}} """ - @spec change_container(Container.t()) :: Changeset.t() - @spec change_container(Container.t(), map()) :: Changeset.t() + @spec change_container(Container.t() | Container.new_container()) :: Changeset.t() + @spec change_container(Container.t() | Container.new_container(), attrs :: map()) :: + Changeset.t() def change_container(container, attrs \\ %{}), do: container |> Container.changeset(attrs) + + @doc """ + Adds a tag to a container + + ## Examples + + iex> add_tag!(container, tag) + %Container{} + + iex> add_tag!(container_id, tag_id) + %Container{} + """ + @spec add_tag!(Container.t(), Tag.t()) :: Container.t() + def add_tag!(%{id: container_id}, %{id: tag_id}), do: add_tag!(container_id, tag_id) + + @spec add_tag!(Container.id(), Tag.id()) :: Container.t() + def add_tag!(container_id, tag_id) + when not (container_id |> is_nil()) and not (tag_id |> is_nil()) do + %ContainerTag{} + |> ContainerTag.changeset(%{"container_id" => container_id, "tag_id" => tag_id}) + |> Repo.insert!() + end + + @doc """ + Removes a tag from a container + + ## Examples + + iex> remove_tag!(container, tag) + %Container{} + + iex> remove_tag!(container_id, tag_id) + %Container{} + """ + @spec remove_tag!(Container.t(), Tag.t()) :: Container.t() + def remove_tag!(%{id: container_id}, %{id: tag_id}), do: remove_tag!(container_id, tag_id) + + @spec remove_tag!(Container.id(), Tag.id()) :: Container.t() + def remove_tag!(container_id, tag_id) + when not (container_id |> is_nil()) and not (tag_id |> is_nil()) do + Repo.delete_all( + from ct in ContainerTag, + where: ct.container_id == ^container_id, + where: ct.tag_id == ^tag_id + ) + end end diff --git a/lib/cannery/invites.ex b/lib/cannery/invites.ex index 1399802c..bf8ab43e 100644 --- a/lib/cannery/invites.ex +++ b/lib/cannery/invites.ex @@ -4,7 +4,7 @@ defmodule Cannery.Invites do """ import Ecto.Query, warn: false - alias Ecto.{Changeset, UUID} + alias Ecto.{Changeset} alias Cannery.{Accounts.User, Invites.Invite, Repo} @invite_token_length 20 @@ -35,7 +35,7 @@ defmodule Cannery.Invites do ** (Ecto.NoResultsError) """ - @spec get_invite!(Ecto.UUID.t()) :: Invite.t() + @spec get_invite!(Invite.id()) :: Invite.t() def get_invite!(id), do: Repo.get!(Invite, id) @doc """ @@ -49,7 +49,7 @@ defmodule Cannery.Invites do iex> get_invite_by_token("invalid_token") nil """ - @spec get_invite_by_token(String.t() | nil) :: Invite.t() | nil + @spec get_invite_by_token(token :: String.t() | nil) :: Invite.t() | nil def get_invite_by_token(nil), do: nil def get_invite_by_token(""), do: nil @@ -96,22 +96,17 @@ defmodule Cannery.Invites do {:error, %Ecto.Changeset{}} """ - @spec create_invite(user :: User.t(), attrs :: map()) :: + @spec create_invite(User.t() | User.id(), attrs :: map()) :: {:ok, Invite.t()} | {:error, Changeset.t()} def create_invite(%{id: user_id}, attrs), do: create_invite(user_id, attrs) - @spec create_invite(user_id :: UUID.t(), attrs :: map()) :: - {:ok, Invite.t()} | {:error, Changeset.t()} def create_invite(user_id, attrs) when not (user_id |> is_nil()) do - attrs = - attrs - |> Map.merge(%{ - "user_id" => user_id, - "token" => - :crypto.strong_rand_bytes(@invite_token_length) - |> Base.url_encode64() - |> binary_part(0, @invite_token_length) - }) + token = + :crypto.strong_rand_bytes(@invite_token_length) + |> Base.url_encode64() + |> binary_part(0, @invite_token_length) + + attrs = attrs |> Map.merge(%{"user_id" => user_id, "token" => token}) %Invite{} |> Invite.changeset(attrs) |> Repo.insert() end @@ -128,10 +123,9 @@ defmodule Cannery.Invites do {:error, %Ecto.Changeset{}} """ - @spec update_invite(Invite.t(), map()) :: {:ok, Invite.t()} | {:error, Ecto.Changeset.t()} - def update_invite(invite, attrs) do - invite |> Invite.changeset(attrs) |> Repo.update() - end + @spec update_invite(Invite.t(), attrs :: map()) :: + {:ok, Invite.t()} | {:error, Ecto.Changeset.t()} + def update_invite(invite, attrs), do: invite |> Invite.changeset(attrs) |> Repo.update() @doc """ Deletes a invite. @@ -146,9 +140,19 @@ defmodule Cannery.Invites do """ @spec delete_invite(Invite.t()) :: {:ok, Invite.t()} | {:error, Ecto.Changeset.t()} - def delete_invite(invite) do - Repo.delete(invite) - end + def delete_invite(invite), do: invite |> Repo.delete() + + @doc """ + Deletes a invite. + + ## Examples + + iex> delete_invite(invite) + %Invite{} + + """ + @spec delete_invite!(Invite.t()) :: Invite.t() + def delete_invite!(invite), do: invite |> Repo.delete!() @doc """ Returns an `%Ecto.Changeset{}` for tracking invite changes. @@ -159,9 +163,7 @@ defmodule Cannery.Invites do %Ecto.Changeset{data: %Invite{}} """ - @spec change_invite(Invite.t()) :: Ecto.Changeset.t() - @spec change_invite(Invite.t(), map()) :: Ecto.Changeset.t() - def change_invite(invite, attrs \\ %{}) do - Invite.changeset(invite, attrs) - end + @spec change_invite(Invite.t() | Invite.new_invite()) :: Ecto.Changeset.t() + @spec change_invite(Invite.t() | Invite.new_invite(), attrs :: map()) :: Ecto.Changeset.t() + def change_invite(invite, attrs \\ %{}), do: invite |> Invite.changeset(attrs) end diff --git a/lib/cannery/tags.ex b/lib/cannery/tags.ex index 23dbee19..5ff7ad18 100644 --- a/lib/cannery/tags.ex +++ b/lib/cannery/tags.ex @@ -4,9 +4,8 @@ defmodule Cannery.Tags do """ import Ecto.Query, warn: false - alias Cannery.{Accounts, Repo} - - alias Cannery.Tags.Tag + alias Cannery.{Accounts.User, Repo, Tags.Tag} + alias Ecto.{Changeset} @doc """ Returns the list of tags. @@ -17,14 +16,9 @@ defmodule Cannery.Tags do [%Tag{}, ...] """ - @spec list_tags(Accounts.User.t()) :: [Tag.t()] - def list_tags(%{id: user_id}) do - list_tags(user_id) - end - - def list_tags(user_id) do - Repo.all(from t in Tag, where: t.user_id == ^user_id) - end + @spec list_tags(User.t() | User.id()) :: [Tag.t()] + def list_tags(%{id: user_id}), do: list_tags(user_id) + def list_tags(user_id), do: Repo.all(from t in Tag, where: t.user_id == ^user_id) @doc """ Gets a single tag. @@ -40,7 +34,7 @@ defmodule Cannery.Tags do ** (Ecto.NoResultsError) """ - @spec get_tag!(Ecto.UUID.t()) :: Tag.t() + @spec get_tag!(Tag.id()) :: Tag.t() def get_tag!(id), do: Repo.get!(Tag, id) @doc """ @@ -52,13 +46,11 @@ defmodule Cannery.Tags do {:ok, %Tag{}} iex> create_tag(%{field: bad_value}) - {:error, %Ecto.Changeset{}} + {:error, %Changeset{}} """ - @spec create_tag(map()) :: {:ok, Tag.t()} | {:error, Ecto.Changeset.t()} - def create_tag(attrs) do - %Tag{} |> Tag.changeset(attrs) |> Repo.insert() - end + @spec create_tag(attrs :: map()) :: {:ok, Tag.t()} | {:error, Changeset.t()} + def create_tag(attrs), do: %Tag{} |> Tag.changeset(attrs) |> Repo.insert() @doc """ Updates a tag. @@ -69,13 +61,11 @@ defmodule Cannery.Tags do {:ok, %Tag{}} iex> update_tag(tag, %{field: bad_value}) - {:error, %Ecto.Changeset{}} + {:error, %Changeset{}} """ - @spec update_tag(Tag.t(), map()) :: {:ok, Tag.t()} | {:error, Ecto.Changeset.t()} - def update_tag(tag, attrs) do - tag |> Tag.changeset(attrs) |> Repo.update() - end + @spec update_tag(Tag.t(), attrs :: map()) :: {:ok, Tag.t()} | {:error, Changeset.t()} + def update_tag(tag, attrs), do: tag |> Tag.changeset(attrs) |> Repo.update() @doc """ Deletes a tag. @@ -86,28 +76,36 @@ defmodule Cannery.Tags do {:ok, %Tag{}} iex> delete_tag(tag) - {:error, %Ecto.Changeset{}} + {:error, %Changeset{}} """ - @spec delete_tag(Tag.t()) :: {:ok, Tag.t()} | {:error, Ecto.Changeset.t()} - def delete_tag(tag) do - Repo.delete(tag) - end + @spec delete_tag(Tag.t()) :: {:ok, Tag.t()} | {:error, Changeset.t()} + def delete_tag(tag), do: tag |> Repo.delete() @doc """ - Returns an `%Ecto.Changeset{}` for tracking tag changes. + Deletes a tag. + + ## Examples + + iex> delete_tag!(tag) + %Tag{} + + """ + @spec delete_tag!(Tag.t()) :: Tag.t() + def delete_tag!(tag), do: tag |> Repo.delete!() + + @doc """ + Returns an `%Changeset{}` for tracking tag changes. ## Examples iex> change_tag(tag) - %Ecto.Changeset{data: %Tag{}} + %Changeset{data: %Tag{}} """ - @spec change_tag(Tag.t()) :: Ecto.Changeset.t() - @spec change_tag(Tag.t(), map()) :: Ecto.Changeset.t() - def change_tag(tag, attrs \\ %{}) do - Tag.changeset(tag, attrs) - end + @spec change_tag(Tag.t() | Tag.new_tag()) :: Changeset.t() + @spec change_tag(Tag.t() | Tag.new_tag(), attrs :: map()) :: Changeset.t() + def change_tag(tag, attrs \\ %{}), do: Tag.changeset(tag, attrs) @doc """ Get a random tag bg_color in `#ffffff` hex format