Skip to content

Commit 2035a51

Browse files
bordeuxclaude
andcommitted
feat: add logic functions (default, coalesce, ternary, in_range)
Implement 4 conditional logic functions for enhanced template control: - default(value, default) - Return default if value is falsy - coalesce(values) - Return first non-null value - ternary(condition, true_val, false_val) - Ternary operator - in_range(value, min, max) - Check if value in range (inclusive) The default function treats the following as falsy: null, undefined, false, 0, empty string, and empty arrays. The ternary function uses MiniJinja's is_true() for consistent truthiness evaluation. Features: - Comprehensive falsy value detection in default() - Array-based value precedence in coalesce() - Truthy/falsy evaluation in ternary() - Inclusive range checking with floats support - Error handling for invalid inputs Testing: - 36 unit tests in tests/test_logic_functions.rs - 37 integration test cases in tests/integration/tests/20_logic_functions.sh - Combined use cases demonstrating real-world patterns - All tests passing, clippy clean Use cases: - Configuration fallbacks and defaults - Multi-level precedence (env -> config -> default) - Conditional rendering based on dynamic values - Resource usage validation and range checking - Environment-based configuration switching Files created: - src/functions/logic.rs - Logic function implementations - tests/test_logic_functions.rs - Unit tests - tests/integration/tests/20_logic_functions.sh - Integration tests Updated: - README.md - Added Logic Functions section with documentation - TODO.md - Marked 4 logic functions as complete - src/functions/mod.rs - Registered logic functions All tests passing, clippy clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 434481f commit 2035a51

6 files changed

Lines changed: 1148 additions & 4 deletions

File tree

README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,6 +2570,133 @@ Python files:
25702570
{% endif %}
25712571
```
25722572
2573+
### Logic Functions
2574+
2575+
Conditional logic and default value handling.
2576+
2577+
#### `default(value, default)`
2578+
2579+
Return default value if the provided value is falsy.
2580+
2581+
**Arguments:**
2582+
- `value` (required): Value to check
2583+
- `default` (required): Default value to return if value is falsy
2584+
2585+
**Returns:** The value if truthy, otherwise the default
2586+
2587+
**Falsy values:** `null`, `undefined`, `false`, `0`, empty string `""`, empty array `[]`
2588+
2589+
**Example:**
2590+
```jinja
2591+
{# Use default for empty string #}
2592+
{{ default(value="", default="N/A") }}
2593+
{# Output: N/A #}
2594+
2595+
{# Use actual value if truthy #}
2596+
{{ default(value="Hello", default="N/A") }}
2597+
{# Output: Hello #}
2598+
2599+
{# Configuration with defaults #}
2600+
{% set config = {"port": 8080} %}
2601+
Host: {{ default(value=config.host, default="localhost") }}
2602+
Port: {{ default(value=config.port, default=3000) }}
2603+
```
2604+
2605+
#### `coalesce(values)`
2606+
2607+
Return the first non-null value from an array.
2608+
2609+
**Arguments:**
2610+
- `values` (required): Array of values to check
2611+
2612+
**Returns:** First value that is not null/undefined, or null if all are null
2613+
2614+
**Example:**
2615+
```jinja
2616+
{# Find first non-null value #}
2617+
{% set a = none %}
2618+
{% set b = none %}
2619+
{% set c = "found" %}
2620+
{{ coalesce(values=[a, b, c]) }}
2621+
{# Output: found #}
2622+
2623+
{# Configuration precedence #}
2624+
{% set env_host = none %}
2625+
{% set config_host = "prod.example.com" %}
2626+
{% set default_host = "localhost" %}
2627+
Host: {{ coalesce(values=[env_host, config_host, default_host]) }}
2628+
{# Output: Host: prod.example.com #}
2629+
```
2630+
2631+
#### `ternary(condition, true_val, false_val)`
2632+
2633+
Ternary operator - return one value based on a condition.
2634+
2635+
**Arguments:**
2636+
- `condition` (required): Boolean condition to evaluate
2637+
- `true_val` (required): Value to return if condition is true
2638+
- `false_val` (required): Value to return if condition is false
2639+
2640+
**Returns:** `true_val` if condition is truthy, otherwise `false_val`
2641+
2642+
**Example:**
2643+
```jinja
2644+
{# Simple ternary #}
2645+
{{ ternary(condition=true, true_val="Yes", false_val="No") }}
2646+
{# Output: Yes #}
2647+
2648+
{# With comparison #}
2649+
{% set score = 85 %}
2650+
Result: {{ ternary(condition=score >= 60, true_val="Pass", false_val="Fail") }}
2651+
{# Output: Result: Pass #}
2652+
2653+
{# Status indicator #}
2654+
{% set cpu_usage = 75 %}
2655+
Status: {{ ternary(
2656+
condition=cpu_usage > 90,
2657+
true_val="Critical",
2658+
false_val="Normal"
2659+
) }}
2660+
```
2661+
2662+
#### `in_range(value, min, max)`
2663+
2664+
Check if a numeric value is within a range (inclusive).
2665+
2666+
**Arguments:**
2667+
- `value` (required): Numeric value to check
2668+
- `min` (required): Minimum value (inclusive)
2669+
- `max` (required): Maximum value (inclusive)
2670+
2671+
**Returns:** `true` if min <= value <= max, `false` otherwise
2672+
2673+
**Example:**
2674+
```jinja
2675+
{# Check if in range #}
2676+
{{ in_range(value=50, min=0, max=100) }}
2677+
{# Output: true #}
2678+
2679+
{# Validate port number #}
2680+
{% set port = 8080 %}
2681+
{% if in_range(value=port, min=1024, max=65535) %}
2682+
Valid port number
2683+
{% else %}
2684+
Invalid port number
2685+
{% endif %}
2686+
2687+
{# Temperature range check #}
2688+
{% set temp = 22 %}
2689+
Comfortable: {{ in_range(value=temp, min=18, max=25) }}
2690+
2691+
{# Resource usage validation #}
2692+
{% set cpu = 75.5 %}
2693+
{% if in_range(value=cpu, min=0, max=80) %}
2694+
CPU usage normal
2695+
{% else %}
2696+
CPU usage high
2697+
{% endif %}
2698+
```
2699+
25732700
### Math Functions
25742701
25752702
Perform mathematical calculations and operations.

TODO.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ This document contains ideas for new functions and features to make tmpltool mor
210210
*Enhanced conditional logic*
211211

212212
**General Logic:**
213-
- [ ] `default(value, default)` - Return default if value is falsy
214-
- [ ] `coalesce(values...)` - Return first non-null value
215-
- [ ] `ternary(condition, true_val, false_val)` - Ternary operator
216-
- [ ] `in_range(value, min, max)` - Check if value in range
213+
- [x] `default(value, default)` - Return default if value is falsy
214+
- [x] `coalesce(values...)` - Return first non-null value
215+
- [x] `ternary(condition, true_val, false_val)` - Ternary operator
216+
- [x] `in_range(value, min, max)` - Check if value in range
217217

218218
**Array Predicates:**
219219
- [x] `array_any(array, predicate)` - Check if any item matches

0 commit comments

Comments
 (0)