defmodule Zoeyscomputer.IdGenerator do @moduledoc """ Generates URL-friendly unique IDs """ @alphabet "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" @size 7 @doc """ Generates a random ID with default length of 7 characters using URL-friendly characters. ## Examples iex> IdGenerator.generate() "f3k9m4z" """ def generate(size \\ @size) do alphabet_length = String.length(@alphabet) 1..size |> Enum.reduce([], fn _, acc -> position = :rand.uniform(alphabet_length) - 1 char = String.at(@alphabet, position) [char | acc] end) |> Enum.join("") end @doc """ Generates a random ID and ensures it's unique by checking against a provided function. ## Examples iex> IdGenerator.generate_unique(&MyApp.id_exists?/1) "x7k9m4z" """ def generate_unique(exists_fn, attempts \\ 0) def generate_unique(exists_fn, attempts) when attempts < 5 do id = generate() if exists_fn.(id) do generate_unique(exists_fn, attempts + 1) else id end end def generate_unique(_exists_fn, _attempts) do raise "Failed to generate unique ID after 5 attempts" end end