RulEx.Behaviour behaviour (RulEx v1.0.0) View Source
This is the main behaviour describing RulEx and all the available callbacks and functions needed to fully implement rules evaluation.
Optionally, using RulEx.Behaviour to generate your custom RulEx module can
also implement the RulEx.Encoding behaviour.
Usage
A custom RulEx module can be defined by simply using RulEx.Behaviour
defmodule MyApp.Rules do
use RulEx.Behaviour
endWhen using the default set of rules defined by RulEx, this is not needed as
a default implementing already exists in RulEx.
Extending RulEx operands
RulEx behaviour provides the ability to extend it's supported operands arbitrarily
via the operand/3 callback, by default this will yield an error for all non
reserved operands as defined by the type RulEx.op.
defmodule MyApp.CustomRules do
use RulEx.Behaviour
# Here we're matching against our custom operand name
# afterwards we assert that the single expression
# given to us will yield `nil`.
#
# A catchall operand for all non-implemented operands
# exists and will yield back an error.
#
def operand("nil?", [arg], db) do
with value <- value(arg, db),
do: {:ok, is_nil(value)}
end
endDefining a default encoding mechanism
RulEx behaviour optionally allows you to provide a custom encoding mechanism to translate RulEx expression into whatever encoding you want/need.
This is achieve by either setting the application environment to define a config
for under RulEx.Behaviour key with a keyword list with :default key set
to the encoding module (implementing the behaviour RulEx.Encoding).
# In your `config/config.exs`
config :rul_ex, RulEx.Behaviour, default: MyApp.RulEx.EncoderFurther more, when defining the module you can pass encoder option when using
this behaviour as such.
defmodule MyApp.CustomRules do
use RulEx.Behaviour, encoder: MyApp.RulEx.Encoder
endDo note that passing the :encoder option overrides any application configurations
set in the environment.
You can disable the encoder behaviour all together by passing the option
:without_encoder when using this behaviour, as such.
defmodule MyApp.CustomRules do
use RulEx.Behaviour, :without_encoder
endIf no explicit encoding mechanism is provided, an the option
:without_encoderisn't passed, then using this behaviour to build your custom RulEx module will useRulEx.Encoding.Jsonas an encoder to implement theRulEx.Encodingbehaviour.
Link to this section Summary
Callbacks
Given a RulEx expression (defined by the type RulEx.t), and a databag holding
any contextual variable info (facts, implementing the protocol RulEx.DataBag),
evaluate the expression against the databag and yield the result.
Exactly identical to RulEx.Behaviour.eval/2 but raises RulEx.EvalError in case of errors.
Validate that the given term is a valid RulEx expression as defined by RulEx.t.
This function can be used to extend RulEx' defined operands arbitrarily by behaviour implementors.
Given a RulEx value expression (defined by the type RulEx.t of operands :val or :var),
and a databag holding any contextual variable info (facts, implementing the protocol
RulEx.DataBag), evaluate the value expression against the databag
and yield the result.
Exactly identical to RulEx.Behaviour.value/2 but raises RulEx.EvalError in case of errors.
Link to this section Callbacks
Specs
eval(RulEx.t(), RulEx.DataBag.t()) :: {:ok, boolean()} | {:error, term()}
Given a RulEx expression (defined by the type RulEx.t), and a databag holding
any contextual variable info (facts, implementing the protocol RulEx.DataBag),
evaluate the expression against the databag and yield the result.
This function will return an error if the expression given to it is an expression
for the operands :val or :var, as those expressions yield any arbitrary value
instead of a boolean result defining whether the RulEx expression is truthy
or falsy given the facts provided (via the databag).
Specs
eval!(RulEx.t(), RulEx.DataBag.t()) :: boolean() | no_return()
Exactly identical to RulEx.Behaviour.eval/2 but raises RulEx.EvalError in case of errors.
Specs
Validate that the given term is a valid RulEx expression as defined by RulEx.t.
Specs
operand(String.t(), RulEx.arg(), RulEx.DataBag.t()) :: {:ok, boolean()} | {:error, term()}
This function can be used to extend RulEx' defined operands arbitrarily by behaviour implementors.
This function will never execute for any of the RulEx reserved operands, as defined
by the type RulEx.op.
Specs
value({:var | :val, [RulEx.arg()]}, RulEx.DataBag.t()) ::
{:ok, any()} | {:error, term()}
Given a RulEx value expression (defined by the type RulEx.t of operands :val or :var),
and a databag holding any contextual variable info (facts, implementing the protocol
RulEx.DataBag), evaluate the value expression against the databag
and yield the result.
This function will return an error if the given any expression except those of
the operands :val or :var.
If the resolved value does not match the type specified in the expression this function
will yield back an error. If given a :var expression, this function should
yield back an error if the databag doesn't hold a value for the requested
variable.
This function will yield an error if given any expression that isn't a RulEx :var or
:var expression, regardless of its correctness as a RulEx expression.
Specs
value!({:var | :val, [RulEx.arg()]}, RulEx.DataBag.t()) :: any() | no_return()
Exactly identical to RulEx.Behaviour.value/2 but raises RulEx.EvalError in case of errors.