A Specification Pattern implementation in Elixir.
Using brex
you can easily
- define
- compose and
- evaluate
business rules to dynamically drive the flow of your application.
Brex
was built to allow you to define and compose rules to evaluate them later. This enables you to build your rules from some kind of configuration, be it a database, a CSV or JSON or anything else.
Maybe you want to allow your customer to create dynamic rules for sending out emails or push notifications? Or you want to decide on the type of event to trigger based on incoming data? Or you think bigger and want to create some kind of flow chart interface?
Whatever your particular use-case, Brex
has you covered when it comes to composition of rules.
The lowest building stone of Brex
is a rule. A rule can have many shapes, for example this is a rule:
&is_list/1
This is a rule too:
Brex.all([&is_list/1, &(length(&1) > 0)])
Or this:
defmodule MyRule do
@behaviour Brex.Rule
@impl true
def evaluate(:foo), do: true
def evaluate(:bar), do: false
end
Also this:
defmodule MyStruct do
use Brex.Rule.Struct
defstruct [:foo]
def evaluate(%{foo: foo}, value) do
foo == value
end
end
Well great that you ask, that's simple too!
iex> Brex.satisfies? MyRule, :foo
true
As you can see, Brex
is flexible and easy to use. All of this is based on the Brex.Rule.Evaluable
protocol, if you're really interested, take a look at Brex.Rule
which talks about the possible rule types a little bit more.
Also, as you might have noticed, I used an all/1
function in the examples
above. This is the compose part of Brex
: it allows you to link rules
using boolean logic.
It currently supports:
all
any
none
I think the names speak for themself.
You can define your own operators, if you're interested then take a look at the Brex.Operator
module.
Simply add brex
to your list of dependencies in your mix.exs
:
def deps do
[
{:brex, "~> 0.1.0"}
]
end
Right now, there is no need for any kind of configuration in Brex
. In case you see some need for it, please open an issue.