require IEx; defmodule Haiku do @moduledoc """ Generates memorable names similar to Xaddress or Heroku. You can configure Haiku to use custom words and functions in your config/config.exs: config :haiku, delimiter: '.', range: 9999, adjectives: ~w(autumn hidden bitter misty}, nouns: ~w(meadow sun glade bird} reducer_module: Haiku.Custom reducer_function: :custom_reduce Note that `reducer_function/4` has 4-arity and expects the following order: [delimiter, adjective, noun, number]. """ alias Haiku.Config @delimiter Config.delimiter @range Config.range @adjectives Config.adjectives @nouns Config.nouns @reducer_module Config.reducer_module @reducer_function Config.reducer_function @type build_args :: keyword() @doc """ Returns a new haiku-formatted name. iex> Haiku.build "quiet-morning-5933" iex> Haiku.build(delimiter: '.') "quiet.morning.5933" """ @spec build(build_args) :: String.t def build, do: _build() def build(delimiter: delimiter), do: _build(delimiter) def build(range: range), do: _build(@delimiter, range) def build(delimiter: delimiter, range: range), do: _build(delimiter, range) defp _build(delimiter \\ @delimiter, range \\ @range) do adjective = Enum.random(@adjectives) noun = Enum.random(@nouns) number = if range > 0, do: random(range) _reduce(delimiter, adjective, noun, number) end # Reduces arguments to a single string defp _reduce(delimiter, adjective, noun, number) do if @reducer_module && @reducer_function do apply(@reducer_module, @reducer_function, [delimiter, adjective, noun, number]) else "#{adjective}#{delimiter}#{noun}#{if number, do: delimiter}#{number}" end end # Generates a random number with range from 0 to n defp random(n) do :rand.uniform(n) end end