Skip to main content

lib/fakererer/blog.ex

defmodule Fakererer.Blog do
  @moduledoc """
  Functions for generating fake blog post data.

  Supports locale-aware generation via the `localize` macro.
  Each locale provides culturally appropriate titles, tags, and content patterns.
  """

  import Fakererer, only: [localize: 1]

  @doc """
  Returns a random blog post title.

  ## Examples

      iex> Fakererer.Blog.title()
      "How to Build Scalable Systems"
      iex> Fakererer.Blog.title()
      "The Future of Artificial Intelligence"
  """
  @spec title() :: String.t()
  localize(:title)

  @doc """
  Returns a random short info / excerpt for a blog post (1-2 sentences).

  ## Examples

      iex> Fakererer.Blog.short_info()
      "A comprehensive guide to building modern web applications with best practices."
      iex> Fakererer.Blog.short_info()
      "Exploring the latest trends in machine learning and their real-world applications."
  """
  @spec short_info() :: String.t()
  localize(:short_info)

  @doc """
  Returns a random list of tags for a blog post (2-5 tags).

  ## Examples

      iex> Fakererer.Blog.tags()
      ["elixir", "phoenix", "web"]
      iex> Fakererer.Blog.tags()
      ["ai", "machine-learning", "deep-learning", "python"]
  """
  @spec tags() :: [String.t()]
  localize(:tags)

  @doc """
  Returns random blog post content as a string of approximately 20 sentences.
  Sentences are separated by spaces and end with proper punctuation.

  ## Examples

      iex> content = Fakererer.Blog.content()
      iex> sentence_count = content |> String.split(~r/[.!?]+\s*/) |> length()
      iex> sentence_count in 18..22
      true
  """
  @spec content() :: String.t()
  localize(:content)

  @doc """
  Returns a complete blog post as a map with :title, :short_info, :tags, and :content.

  ## Examples

      iex> post = Fakererer.Blog.post()
      iex> is_map(post)
      true
      iex> Map.has_key?(post, :title)
      true
      iex> Map.has_key?(post, :short_info)
      true
      iex> Map.has_key?(post, :tags)
      true
      iex> Map.has_key?(post, :content)
      true
  """
  @spec post() :: %{
          title: String.t(),
          short_info: String.t(),
          tags: [String.t()],
          content: String.t()
        }
  def post do
    %{
      title: title(),
      short_info: short_info(),
      tags: tags(),
      content: content()
    }
  end
end