README.md

## AtomEnforcer

`AtomEnforcer` exists to solve a problem encountered in production code- preventing 
run-time errors for mismatched atoms between sends and receieves, especially in GenServer
APIs and `handle_((call|cast|info)` function heads.

The strategy is to explicitly allow certain atoms to exist within a module, and then, at
compile time, raise an error if an atom is used which has not been allowed.

### Getting Started

1. add `{:atom_enforcer, "~> 0.1"},` to your `mix.deps`
2. add `use AtomEnforcer, allowed_atoms: <atoms you want to use>` to a module
3. find your atom typos at compile time now

### API

The only API for `AtomEnforcer` is the `__using__` macro and it's options:

  - `allowed_atoms`: a single atom or a list of atoms which are allowed to exist in this
    module.
  - `allow_common`: (default true) automatically whitelists `[:ok, :error, true, false, nil]`
  - `infer_genserver`: (default true) If the module is a GenServer, automatically whitelists
    atoms used in genserver callbacks. See documentation for the full list.

### Salient Example

```elixir
#TODO: improve this example 
defmodule SomeGenServer do
  use GenServer
  use AtomEnforcer, allowed_atoms: [:api_call_1]

  def start_link([]) do
    GenServer.start_link(__MODULE__, [], [name: __MODULE__])
  end

  def api_call_1(args) do
    GenServer.call(__MODULE__, {:api_call_1, args}) 
  end

  def init([]), do: {:ok, []}

  # The misspelling on the next line will cause a CompileError to be thrown
  def handle_call({:ap_call_1, args}, _from, state) do
    {:reply, args, state}
  end

end

```

### Closing Comments

Please drop me a note if you end up using AtomEnforcer in something cool, or file an
issue if you have difficulty, bugs, or ideas for a better API.