Skip to content

Compiles dispatch rules to an Erlang module for quick dispatch matching.

License

Notifications You must be signed in to change notification settings

naga-framework/dispatch_compiler

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dispatch_compiler Build Status

Compiles dispatch rules to an Erlang module for quick matching.

The dispatch compiler takes a list of dispatch rules and creates an Erlang module that matches those rules.

The compiled Erlang module exports a single function: match/2.

Dispatch rules

Dispatch rules are lists of tokens with some extra information:

{name, ["foo", "bar", id], controller_name, [controller,options]}

The path parts can be one of the following:

  • a string "foo". This is translated to a binary and must match literally
  • an atom id this binds the variable to the token and is returned
  • the atom '*', this binds to any left tokens, which could be an empty list
  • regular expressions {id, "^[0-9]+$"}
  • regular expressions with re compile options {id, "^[a-z]+$", [caseless]}

It is also possible to define functions to perform runtime checks on the tokens.

Functions can be defined as:

  • A module, function pair: {var, {foo, bar}}, this will call foo:bar(Token, Context)
  • A module, function, args triple: {var, {foo, bar, [some, args]}}, this will call foo:bar(Token, Context, some, args)
  • A function with a single arg: {var, fun(<<C,Rest/binary>>) -> C < $z end}
  • A function with a two arguments: {var, fun(<<C,Rest/binary>>, Context) -> C < $z end}

Functions must return one of the following

  • true on a match
  • false if not matched
  • {ok, Term} to bind the variable to the return Term

Usage

First compile the dispatch rules to an Erlang module:

Rules = [
    {test, ["a", v], foo, []},
    {wildcard, ["w", '*'], foo, []}
],
ok = dispatch_compiler:compile_load('mydispatch', Rules).

Now the compiled module can be used to match (the undefined will be passed as Context to any functions in the dispatch rules):

1> mydispatch:match([<<"a">>, <<"b">>], undefined).
{ok, { {test, ["a", v], foo, []}, [{v,<<"b">>}]}}

The return value contains the matched dispatch rule and any bound variables. The first matching rule is returned.

Another example showing a matching wildcard:

2> mydispatch:match([<<"w">>, <<"b">>, <<"c">>], undefined).
{ok, { {wildcard, ["w", '*'], foo, []}, [{'*',[<<"b">>, <<"c">>]}]}}

If no dispatch rule could be matched, then fail is returned:

3> mydispatch:match([<<"a">>, <<"b">>, <<"c">>], undefined).
fail

Tests

Run make test to run the tests.

About

Compiles dispatch rules to an Erlang module for quick dispatch matching.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Erlang 97.6%
  • Makefile 2.4%