Skip to main content

Context Expressions

Context expressions define when an override should apply. In SuperTOML, contexts are defined using the _context_ object with equality matching.

Context Matching with _context_

The _context_ object defines when an override applies:

[[overrides]]
_context_ = { vehicle_type = "cab" }
per_km_rate = 25.0

This override applies when the runtime context has vehicle_type = "cab".

Multiple Conditions

All conditions in _context_ must match (AND logic):

[[overrides]]
_context_ = { city = "Bangalore", vehicle_type = "cab" }
per_km_rate = 22.0

This applies when both city = "Bangalore" AND vehicle_type = "cab".

How Matching Works

A context matches when:

  • All dimension values in _context_ equal the corresponding runtime values
  • Unspecified dimensions act as wildcards (match any value)
# Matches any cab ride, regardless of city or time
[[overrides]]
_context_ = { vehicle_type = "cab" }
per_km_rate = 25.0

# Matches only Bangalore cabs
[[overrides]]
_context_ = { city = "Bangalore", vehicle_type = "cab" }
per_km_rate = 22.0

Limitations of _context_

The _context_ object only supports equality matching. It does not support:

  • Inequality (!=)
  • Numeric comparisons (<, >, <=, >=)
  • OR logic
  • Range checks

For these use cases, use LOCAL_COHORT dimensions with JSONLogic definitions.

Complex Conditions with LOCAL_COHORT

When you need conditions beyond simple equality, create a LOCAL_COHORT dimension that derives its value using JSONLogic.

What is JSONLogic?

JSONLogic is a rules engine that allows you to define conditional logic as JSON. SuperTOML uses JSONLogic in the definitions field of cohort dimension schemas.

Common JSONLogic Operations

OperationDescription
EqualityCheck if values are equal
InequalityCheck if values are not equal
Greater thanCheck if value1 > value2
Less thanCheck if value1 < value2
Greater or equalCheck if value1 >= value2
Less or equalCheck if value1 <= value2
In listCheck if value is in array
ANDBoth conditions must be true
OREither condition must be true
NOTNegate a condition

JSONLogic Syntax Examples

The following examples show JSONLogic syntax. Use these patterns in the definitions field:

Equality:        {"==": [value1, value2]}
Inequality: {"!=": [value1, value2]}
Greater than: {">": [value1, value2]}
Less than: {"<": [value1, value2]}
Greater/equal: {">=": [value1, value2]}
Less/equal: {"<=": [value1, value2]}
In list: {"in": [value, array]}
AND: {"and": [condition1, condition2]}
OR: {"or": [condition1, condition2]}
NOT: {"!": condition}

Referencing Dimensions

To reference a dimension value in JSONLogic, use the "var" operator:

{"var": "dimension_name"}

Example - check if hour_of_day >= 18:

{">=": [{"var": "hour_of_day"}, 18]}

Examples

Numeric Range: Time Periods

Create a cohort for time periods (morning rush, evening rush, off-peak):

[dimensions]
hour_of_day = {
position = 3,
schema = { type = "integer", minimum = 0, maximum = 23 }
}

time_period = {
position = 1,
type = "LOCAL_COHORT:hour_of_day",
schema = {
type = "string",
enum = ["morning_rush", "evening_rush", "off_peak"],
definitions = {
morning_rush = { "and": [
{ ">=": [{ "var": "hour_of_day" }, 7] },
{ "<=": [{ "var": "hour_of_day" }, 10] }
]},
evening_rush = { "and": [
{ ">=": [{ "var": "hour_of_day" }, 17] },
{ "<=": [{ "var": "hour_of_day" }, 21] }
]}
}
}
}

# Use the cohort in overrides
[[overrides]]
_context_ = { time_period = "morning_rush" }
surge_factor = 1.5

[[overrides]]
_context_ = { time_period = "evening_rush" }
surge_factor = 2.0

Inequality: Excluding Values

Create a cohort that excludes a specific city:

[dimensions]
city = {
position = 4,
schema = { type = "string", enum = ["Bangalore", "Delhi", "Chennai", "Mumbai"] }
}

is_not_delhi = {
position = 1,
type = "LOCAL_COHORT:city",
schema = {
type = "string",
enum = ["yes", "no"],
definitions = {
yes = { "!=": [{ "var": "city" }, "Delhi"] }
}
}
}

[[overrides]]
_context_ = { is_not_delhi = "yes" }
base_fare = 45.0

OR Logic: Multiple Cities

Create a cohort for a region (multiple cities):

[dimensions]
city = {
position = 4,
schema = { type = "string", enum = ["Bangalore", "Chennai", "Delhi", "Mumbai"] }
}

region = {
position = 1,
type = "LOCAL_COHORT:city",
schema = {
type = "string",
enum = ["south", "north", "west", "otherwise"],
definitions = {
south = { "in": [{ "var": "city" }, ["Bangalore", "Chennai"]] },
north = { "in": [{ "var": "city" }, ["Delhi"]] },
west = { "in": [{ "var": "city" }, ["Mumbai"]] }
}
}
}

[[overrides]]
_context_ = { region = "south" }
per_km_rate = 18.0

[[overrides]]
_context_ = { region = "north" }
per_km_rate = 22.0

Complex Conditions: Peak Hours in Specific City

Combine multiple conditions:

[dimensions]
city = { position = 4, schema = { type = "string" } }
hour_of_day = { position = 3, schema = { type = "integer", minimum = 0, maximum = 23 } }

delhi_peak_hours = {
position = 1,
type = "LOCAL_COHORT:city",
schema = {
type = "string",
enum = ["yes", "no"],
definitions = {
yes = { "and": [
{ "==": [{ "var": "city" }, "Delhi"] },
{ "or": [
{ "and": [
{ ">=": [{ "var": "hour_of_day" }, 8] },
{ "<=": [{ "var": "hour_of_day" }, 10] }
]},
{ "and": [
{ ">=": [{ "var": "hour_of_day" }, 18] },
{ "<=": [{ "var": "hour_of_day" }, 21] }
]}
]}
]}
}
}
}

[[overrides]]
_context_ = { delhi_peak_hours = "yes" }
surge_factor = 2.5

Range Check: Age Groups

[dimensions]
user_age = {
position = 5,
schema = { type = "integer", minimum = 0, maximum = 120 }
}

age_group = {
position = 1,
type = "LOCAL_COHORT:user_age",
schema = {
type = "string",
enum = ["youth", "adult", "senior"],
definitions = {
youth = { "<": [{ "var": "user_age" }, 25] },
senior = { ">=": [{ "var": "user_age" }, 60] }
}
}
}

[[overrides]]
_context_ = { age_group = "youth" }
discount = 0.2

[[overrides]]
_context_ = { age_group = "senior" }
discount = 0.3

Best Practices

1. Use _context_ for Simple Equality

# Good: Simple equality check
[[overrides]]
_context_ = { vehicle_type = "cab" }
per_km_rate = 25.0

2. Use Cohorts for Complex Conditions

# Good: Complex condition via cohort
[dimensions]
hour_of_day = { position = 3, schema = { type = "integer", minimum = 0, maximum = 23 } }

is_peak_hour = {
position = 1,
type = "LOCAL_COHORT:hour_of_day",
schema = {
type = "string",
enum = ["yes", "no"],
definitions = {
yes = { "or": [
{ "and": [
{ ">=": [{ "var": "hour_of_day" }, 7] },
{ "<=": [{ "var": "hour_of_day" }, 10] }
]},
{ "and": [
{ ">=": [{ "var": "hour_of_day" }, 17] },
{ "<=": [{ "var": "hour_of_day" }, 21] }
]}
]}
}
}
}

[[overrides]]
_context_ = { is_peak_hour = "yes" }
surge_factor = 1.5

3. Name Cohorts Meaningfully

# Good: Clear cohort name
is_premium_user = { ... }
delhi_peak_hours = { ... }
south_region = { ... }

# Avoid: Unclear names
condition_1 = { ... }
check = { ... }

4. Always Include a Default Value

Cohorts should have a default value for unmatched cases:

schema = {
type = "string",
enum = ["yes", "no"], # "no" is the default for unmatched
definitions = {
yes = { ... } # Only define the "yes" condition
}
}

5. Keep Cohort Position Lower Than Base

# Good: Cohort position (1) < base position (4)
city = { position = 4, ... }
region = { position = 1, type = "LOCAL_COHORT:city", ... }

Validation

Context conditions are validated at parse time:

  1. Dimension existence: All dimensions in _context_ must be declared
  2. Value validity: Values must match dimension schemas
  3. Cohort definitions: JSONLogic must be valid and reference existing dimensions

Example Errors

# Error: Unknown dimension
[[overrides]]
_context_ = { unknown_dimension = "value" }
per_km_rate = 25.0
# Error: Dimension 'unknown_dimension' not found

# Error: Invalid enum value
[dimensions]
city = { position = 4, schema = { type = "string", enum = ["Bangalore", "Delhi"] } }

[[overrides]]
_context_ = { city = "Mumbai" }
per_km_rate = 25.0
# Error: Value "Mumbai" not in enum ["Bangalore", "Delhi"]

Summary

Condition TypeMethod
Simple equalityUse _context_ directly
Inequality (!=)Create LOCAL_COHORT with != JSONLogic
Numeric comparison (<, >, <=, >=)Create LOCAL_COHORT with comparison JSONLogic
OR logicCreate LOCAL_COHORT with or JSONLogic
Range checkCreate LOCAL_COHORT with and + comparisons
Membership checkCreate LOCAL_COHORT with in JSONLogic

The _context_ object with equality matching is the primary way to define conditions. For complex conditions, create LOCAL_COHORT dimensions using JSONLogic as the definition language.