Rule Cascade
Examples

Other languages

The same two evaluations from Python, Node.js, Ruby, PHP, Java, shell, Rust, C# and PowerShell through the command, and from Node.js and Python through the WebAssembly module.

Code: examples/engine-clients (README). Every client starts the engine once, sends version, loads the payments bundle, evaluates two requests and prints exactly expected-output.txt:

examples/engine-clients/expected-output.txt
engine: Rule Cascade 1.0.0, bundle format 1.0.0
loaded: acme.payments.transfer 1.0.0
domestic transfer: allow
  warning ORG-TRF-003 Adding a memo makes this transfer easier to reconcile.
blocked country: deny
  error ORG-TRF-001 Transfers to KP are not permitted.

The core of each client is one function: write a request line, read a response line, check it.

From process/client.py:

examples/engine-clients/process/client.py
def call(self, command, **members):
    self.sent += 1
    line = json.dumps({"id": self.sent, "command": command, **members}, ensure_ascii=False)
    try:
        self.process.stdin.write(line.encode("utf-8") + b"\n")
        self.process.stdin.flush()
    except OSError:
        fail("the engine closed its input")
    answer = self.process.stdout.readline()  # a whole line, however long
    if not answer:
        fail("the engine closed its output")
    response = json.loads(answer)
    if response.get("id") != self.sent:
        fail("expected the response to request %d, got %r" % (self.sent, response.get("id")))
    if response.get("ok") is not True:
        error = response.get("error") or {}
        fail("%s: %s" % (error.get("code"), error.get("message")))
    return response["result"]

PHP, Java, shell, Rust, C# and PowerShell follow the same shape in process/; wasm/client.mjs and wasm/client.py run the WebAssembly module inside the client's own process.

Run them

Diagram, described in Mermaid: flowchart LR C[Client process] -- one JSON request per line --> E[rcas engine] E -- one JSON response per line --> C B[(payments bundle)] -. load once .-> E

Get the command

Download and verify rcas, then point the clients at it:

export RULE_CASCADE_ENGINE=$(command -v rule-cascade)

Run one client against the payments bundle

python3 examples/engine-clients/process/client.py conformance/bundles/acme.payments.transfer.bundle.json
engine: Rule Cascade 1.0.0, bundle format 1.0.0
loaded: acme.payments.transfer 1.0.0
domestic transfer: allow
  warning ORG-TRF-003 Adding a memo makes this transfer easier to reconcile.
blocked country: deny
  error ORG-TRF-001 Transfers to KP are not permitted.

Done when the output is exactly expected-output.txt: ... | diff - examples/engine-clients/expected-output.txt prints nothing. The Node.js and Ruby clients (node .../client.mjs, ruby .../client.rb) print the same six lines.

Run every client whose language is installed

sh examples/engine-clients/run-all.sh

On a machine with Python, Node.js, Ruby, Java and a shell, but no PHP, Rust, .NET, PowerShell or the wasmtime Python package:

PASS  process/client.py
PASS  process/client.mjs
PASS  process/client.rb
SKIP  process/client.php (PHP is not installed)
PASS  process/Client.java
PASS  process/client.sh
SKIP  process/client.rs (Rust (cargo) is not installed)
SKIP  process/Client.cs (the .NET SDK is not installed)
SKIP  process/client.ps1 (PowerShell is not installed)
PASS  wasm/client.mjs
SKIP  wasm/client.py (the wasmtime package is not installed: pip install wasmtime)
6 passed, 0 failed, 5 skipped

Done when the last line says 0 failed. Each PASS means that client's output matched expected-output.txt byte for byte; a client whose language is missing is skipped and named.

CI runs the Python, Node.js, Ruby, PHP, Java, shell and Rust clients and both WebAssembly clients on Linux. Client.cs and client.ps1 were written against the documented behaviour of .NET and PowerShell and have not been executed.

Step by step: Run rules from any other language.

On this page