Can’t figure out what the issue is here:
== Compilation error in file lib/twitter_core/tweet_log.ex ==
** (CompileError) lib/twitter_core/tweet_log.ex:19: Twitter.Core.Tweet.struct/0 is undefined, cannot expand struct Twitter.Core.Tweet. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
lib/twitter_core/tweet_log.ex:17: (module)
Here’s the code:
defmodule Twitter.Core.TweetLog do
alias Twitter.Core.{Tweet, TweetLog, User}
defstruct [:user_id, tweets: %{}]
def new(%User{id: user_id}, tweet \\ %{}) when user_id != nil do
case Map.has_key?(tweet, :created) do
false ->
%TweetLog{user_id: user_id}
_ ->
%TweetLog{user_id: user_id}
|> add_tweet(tweet)
end
end
def add_tweet(
%TweetLog{tweets: tweets, user_id: user_id} = tweet_list,
%Tweet{} = tweet
) do
id = UUID.uuid1()
tweet = %{tweet | id: id, user_id: user_id}
new_tweets = Map.put(tweets, id, tweet)
{:ok, %TweetLog{tweet_list | tweets: new_tweets}}
end
def get_last(%TweetLog{tweets: tweets}) do
[head | _tail] =
Enum.sort(tweets, fn {_key1, tweet1}, {_key2, tweet2} ->
case Date.compare(tweet1.created, tweet2.created) do
:lt ->
true
_ ->
false
end
end)
{_key, tweet} = head
tweet
end
def all_tweets(%TweetLog{tweets: tweets}) do
Enum.map(tweets, fn {_tweet_id, tweet} ->
tweet
end)
end
def update_tweet(
%TweetLog{tweets: tweets} = tweet_list,
%Tweet{id: id} = tweet
) do
case Map.fetch(tweets, id) do
{:ok, _} ->
tweet = %{tweet | id: id}
new_tweets = Map.put(tweets, id, tweet)
{:ok, %{tweet_list | tweets: new_tweets}}
:error ->
{:error, :nonexistent_tweet}
end
end
def delete_tweet(%TweetLog{tweets: tweets} = tweet_list, %Tweet{id: tweet_id}) do
case Map.fetch(tweets, tweet_id) do
{:ok, _} ->
new_tweets = Map.delete(tweets, tweet_id)
{:ok, %{tweet_list | tweets: new_tweets}}
:error ->
{:error, :invalid_delete_operation}
end
end
end
Tweet struct exists:
defmodule Twitter.Core.Tweet do
alias Twitter.Core.{Comment, Tweet, User}
@enforce_keys [:content, :title]
defstruct [
:created,
:comments,
:content,
:id,
:likes,
:title,
:user_id
]
def add_comment(
%Tweet{comments: comments} = tweet,
%User{id: user_id},
text
) do
id = UUID.uuid1()
comment = Comment.new(id, user_id, text)
new_comments = Map.put(comments, id, comment)
%Tweet{tweet | comments: new_comments}
end
def delete_comment(%Tweet{comments: comments} = tweet, %Comment{id: comment_id}) do
case Map.fetch(tweet.comments, comment_id) do
{:ok, _} ->
new_comments = Map.delete(comments, comment_id)
{:ok, %{tweet | comments: new_comments}}
:error ->
{:error, :non_existent_comment}
end
end
def new(content, title) when is_binary(content),
do: %Tweet{
created: Timex.now(),
comments: %{},
content: content,
likes: MapSet.new(),
title: title
}
def toggle_like(%Tweet{likes: likes} = tweet, %User{id: user_id}) do
case Enum.find(likes, &(&1 == user_id)) do
nil ->
likes = MapSet.put(likes, user_id)
%{tweet | likes: likes}
_ ->
likes = MapSet.delete(likes, user_id)
%{tweet | likes: likes}
end
end
def update_comment(
%Tweet{comments: comments} = tweet,
%Comment{id: comment_id},
text
) do
case Map.fetch(comments, comment_id) do
{:ok, comment} ->
new_comment = %{comment | text: text}
new_comments = Map.put(comments, comment.id, new_comment)
{:ok, %{tweet | comments: new_comments}}
:error ->
{:error, :non_existent_comment}
end
end
end