Skip to content

GenClient is an elixir library made to generate boilerplate code that I found myself repeatedly writing and changing when working with GenServers

License

Notifications You must be signed in to change notification settings

LukeWood/GenClient

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GenClient

⚠ Don't use this in production ⚠

PragDave's component library is a much more feature complete library and is of much higher quality.

GenClient is an elixir metaprogramming library made to generate boilerplate code that I found myself repeatedly writing and changing when working with GenServers.

Every time I wanted to add or remove a parameter from a GenServer module I needed to do so in several places.

GenClient lets the programmer write their logic in a single location and keep it there.

Example

Here is a module written using a standard GenServer implementation

counter.ex
defmodule Counter do
  defdelegate increment(pid),       to: Client
  defdelegate increment_by(pid, x), to: Client
  defdelegate peek(pid),            to: Client
end
counter/client.ex
defmodule Counter.Client do

  def increment(pid) do
    GenServer.cast(pid, :increment)
  end
  
  def increment_by(pid, x) do
    GenServer.cast(pid, {:increment_by, x})
  end

  def peek(pid) do
    GenServer.call(pid, :peek)
  end

end
counter/server.ex
defmodule Counter.Server do
  def handle_cast(:increment, state) do
    {:no_reply, Counter.Impl.increment(state)}
  end
  
  def handle_cast({:increment_by, x}, state) do
    {:no_reply, Counter.Impl.increment_by(state, x)}
  end
  
  def handle_call(:peek, _from, state) do
    {:reply, state, state}
  end
end
counter/impl.ex
defmodule Counter.Impl do
  def increment(state), do: state + 1
  def increment_by(state, x), do: state + x
end

The Previous Module Can be written using GenClient as follows:

counter.ex
defmodule Counter do
  use GenClient,
    for: Counter.Impl,
    calls: [:peek],
    casts: [:increment, :increment_by]
end
counter/counter.impl.ex
defmodule Counter.Impl do
  # Casts
  def increment(state), do: state + 1
  def increment_by(state, amount), do: state + amount
  
  # Calls
  def peek(state) do
    response = state
    new_state = state
    {response, new_state}
  end
  
end
The resulting api will be exactly the same

Adding as a mix dependency

  def deps do
    [{:gen_client, git:"https://github.com/LukeWood/GenClient"}]
  end

or

def deps do
  [{:gen_client, "~> 1.0.1"}]
end

About

GenClient is an elixir library made to generate boilerplate code that I found myself repeatedly writing and changing when working with GenServers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages