Dmn.Features (dmn v0.1.0)

Copy Markdown View Source

What a caller switches on when it compiles a model, as one option: features: (DD-29).

Dmn.compile(model, features: [:recursion, :dmn_1_1_types])

A feature is a name or a module, and there are two kinds. :recursion is the engine's own: business knowledge models and decision services may invoke themselves or one another, and guarded recursive item definitions retain full finite-value membership and descendant constraint checks (DD-22). Data cycles must cross a context member or list element and cannot cross a function signature. Analysis remains approximate; recursive: :any is a separate legacy FEEL mode, not the behavior of this feature. The others are the extensions of Dmn.Extension (DD-28), by their names (Dmn.Extension.registry/0) or as modules that implement the behaviour. All of them are off unless the caller says so, and nothing in a model can say so: the features are the caller's, as the limits are.

The two options that came first still work, and mean the same:

SpellingIs
recursion: truefeatures: [:recursion]. Only true turns it on, as before: false, "yes" and 1 leave it off
extensions: [...]the extensions in features:, with the same names and modules and the same errors

The spellings add to one another: a feature that any of them names is on, and recursion: false does not turn off a features: that has :recursion. A name that is no feature, a module that is no extension, two extensions that give one name two meanings, and a features: that is not a list are {:error, %Dmn.Error{kind: :compile, code: :invalid_options}} of Dmn.compile/2, with the option that has it in details.option; Dmn.Compiler.compile/2 called directly raises ArgumentError.

iex> Dmn.Features.resolve(features: [:recursion, :dmn_1_1_types])
{:ok, %{recursion: true, extensions: [Dmn.Extension.Dmn11Types]}}
iex> Dmn.Features.resolve(recursion: true, extensions: [:dmn_1_1_types]) == Dmn.Features.resolve(features: [:recursion, :dmn_1_1_types])
true
iex> Dmn.Features.resolve([])
{:ok, %{recursion: false, extensions: []}}
iex> {:error, _message, :features} = Dmn.Features.resolve(features: [:nope])

Summary

Types

t()

What the compiler is given: whether knowledge/data recursion is enabled, and the selected extensions.

Functions

The features that are the engine's own, and not extensions.

The options of a compile with :recursion and :extensions set from the features and :features taken out, so that what reads them reads two keys. The options as they are if they are already so.

What the options of a compile switch on: {:ok, features}, or {:error, message, option} with the option (:features or :extensions) that is wrong. See the module documentation.

Types

t()

@type t() :: %{recursion: boolean(), extensions: [module()]}

What the compiler is given: whether knowledge/data recursion is enabled, and the selected extensions.

Functions

engine()

@spec engine() :: [atom()]

The features that are the engine's own, and not extensions.

normalize!(options)

@spec normalize!(keyword()) :: keyword()

The options of a compile with :recursion and :extensions set from the features and :features taken out, so that what reads them reads two keys. The options as they are if they are already so.

Raises ArgumentError for a feature that is wrong, as Dmn.Compiler.compile/2 does; Dmn.compile/2 has already refused it.

resolve(options)

@spec resolve(keyword()) :: {:ok, t()} | {:error, String.t(), :features | :extensions}

What the options of a compile switch on: {:ok, features}, or {:error, message, option} with the option (:features or :extensions) that is wrong. See the module documentation.