defmodule MopURL do @moduledoc """ URL cleaning service ## Usage: iex> url = "www.google.com/search?q=elixir&source=hp&ei=safsa&oq=elixir&gs_lcp=gfsdsadh" iex> MopURL.start_link(name: MyMopURL) iex> MopURL.clean(MyMopURL, url) {:ok, "https://www.google.com/search?q=elixir"} """ use GenServer alias MopURL.{Cleaner, ValidateURL} @typedoc """ The `:name` provided to MopURL in `start_link/1`. """ @type name() :: atom() @doc """ Start an instance of MopURL ## Options * `:name` - The name of your MopURL instance. This field is required. """ def start_link(opts) do name = Keyword.get(opts, :name) || raise ArgumentError, "must supply a name" # TODO: make rule file configurable GenServer.start_link(__MODULE__, :ok, name: name) end def init(:ok) do {:ok, Cleaner.new()} end def handle_call({:clean, url}, _from, cleaner) do {:reply, clean_procedure(cleaner, url), cleaner} end @doc """ Clean `url` using instance of `mop_url` provided """ @spec clean(name(), String.t()) :: {:ok, String.t()} | {:error, any()} def clean(mop_url, url) do GenServer.call(mop_url, {:clean, url}) end defp clean_procedure(cleaner, url) do with {:ok, url} <- ValidateURL.cast(url), url <- Cleaner.clean(cleaner, url), {:ok, url} <- ValidateURL.cast(url), :ok <- ValidateURL.validate_hostname(url) do {:ok, url} else error -> error end end end