Expression.Context (expression v2.49.1)

Copy Markdown

A helper module for creating a context that can be used with Expression.Eval.

Plain map context

new/2 returns a plain map with lowercased string keys and auto-coerced values. This is the legacy format and remains the default for backwards compatibility.

iex> Expression.Context.new(%{foo: "bar"}) %{"foo" => "bar"} iex> Expression.Context.new(%{FOO: "bar"}) %{"foo" => "bar"} iex> Expression.Context.new(%{foo: %{bar: "baz"}}) %{"foo" => %{"bar" => "baz"}} iex> Expression.Context.new(%{Foo: %{Bar: "baz"}}) %{"foo" => %{"bar" => "baz"}} iex> Expression.Context.new(%{foo: %{bar: 1}}) %{"foo" => %{"bar" => 1}} iex> Expression.Context.new(%{date: "2020-12-13T23:34:45"}) %{"date" => ~U[2020-12-13 23:34:45.0Z]} iex> Expression.Context.new(%{boolean: "true"}) %{"boolean" => true} iex> Expression.Context.new(%{float: 1.234}) %{"float" => 1.234} iex> now = DateTime.utc_now() iex> ctx = Expression.Context.new(%{float: "1.234", nested: %{date: now}}) iex> ctx["float"] 1.234 iex> now == ctx["nested"]["date"] true iex> Expression.Context.new(%{mixed: ["2020-12-13T23:34:45", 1, "true", "binary"]}) %{"mixed" => [~U[2020-12-13 23:34:45.0Z], 1, true, "binary"]}

Options

new/2 accepts the following options:

  • :lowercase_keys - when true (default), all keys are lowercased. Set to false to preserve original casing — the evaluator uses case-insensitive lookup so expressions still resolve correctly.
  • :coerce_strings - when true (default), string values are auto-parsed to their typed equivalents (dates, booleans, numbers). Set to false to preserve all string values as-is.
  • :skip_context_evaluation? - legacy alias for coerce_strings: false.

Structured context with private state

build/2 returns an %Expression.Context{} struct that separates user-visible variables from callback-private state.

Variable resolution (@foo) only reads from vars. Callbacks receive the full struct and can access private for trusted data (database records, tokens, internal IDs) that expression authors must not be able to read.

iex> ctx = Expression.Context.build(%{name: "Jane"}, private: %{number: %{uuid: "abc"}}) iex> ctx.vars["name"] "Jane" iex> ctx.private %{number: %{uuid: "abc"}}

Summary

Functions

Build a structured context with separate variable and private state compartments.

Types

t()

@type t() :: %Expression.Context{private: map(), vars: map()}

Functions

build(vars, opts \\ [])

@spec build(map(), Keyword.t()) :: t()

Build a structured context with separate variable and private state compartments.

Variable resolution (@foo) only reads from vars. Callbacks receive the full struct and can access private for trusted data that expression authors must not be able to read.

Options

  • :private - a map of callback-only data (default: %{})

Any other options are passed through to new/2 for variable normalization.

Examples

iex> ctx = Expression.Context.build(%{name: "Jane"}, private: %{token: "secret"})
iex> ctx.vars["name"]
"Jane"
iex> ctx.private.token
"secret"

new(ctx, opts \\ [])

@spec new(map(), Keyword.t() | nil) :: map()