Skip to content

Commit 4399e70

Browse files
bordeuxclaude
andcommitted
refactor: migrate Object functions to filter_functions (Phase 11)
- Add src/filter_functions/object.rs with ObjectKeys, ObjectValues, ObjectFlatten - Register functions in filter_functions/mod.rs - Update functions/mod.rs to remove migrated function registrations - Add 6 integration tests for filter syntax - Update README.md with dual syntax documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 36ca6bc commit 4399e70

6 files changed

Lines changed: 448 additions & 59 deletions

File tree

README.md

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,7 +2525,7 @@ Set nested value in an object using dot-separated path notation. Creates interme
25252525
{{ to_json(object=config, pretty=true) }}
25262526
```
25272527
2528-
#### `object_keys(object)`
2528+
#### `object_keys(object)` / `| object_keys`
25292529
25302530
Get all keys from an object as an array.
25312531
@@ -2536,38 +2536,28 @@ Get all keys from an object as an array.
25362536
25372537
**Examples:**
25382538
```jinja
2539-
{# Get all keys #}
2539+
{# Function syntax #}
25402540
{% set config = {"host": "localhost", "port": 8080, "debug": true} %}
25412541
{% set keys = object_keys(object=config) %}
25422542
{{ to_json(object=keys) }}
25432543
{# Output: ["host","port","debug"] #}
25442544
2545-
{# Iterate over keys #}
2546-
{% set config = {"host": "localhost", "port": 8080, "debug": true} %}
2547-
Configuration keys:
2548-
{% for key in object_keys(object=config) %}
2549-
- {{ key }}
2550-
{% endfor %}
2551-
{# Output:
2552-
Configuration keys:
2553-
- host
2554-
- port
2555-
- debug
2556-
#}
2545+
{# Filter syntax #}
2546+
{% set keys = config | object_keys %}
2547+
{{ keys | join(sep=", ") }}
2548+
{# Output: host, port, debug #}
25572549
2558-
{# Dynamic configuration display #}
2559-
{% set config = {
2560-
"SERVER_HOST": "localhost",
2561-
"SERVER_PORT": 8080,
2562-
"DATABASE_URL": "postgres://localhost/mydb"
2563-
} %}
2564-
# Environment Variables
2565-
{% for key in object_keys(object=config) %}
2566-
{{ key }}={{ config[key] }}
2550+
{# Iterate over keys with filter syntax #}
2551+
{% for key in config | object_keys %}
2552+
- {{ key }}: {{ config[key] }}
25672553
{% endfor %}
2554+
2555+
{# Chaining - get count of keys #}
2556+
{{ config | object_keys | length }}
2557+
{# Output: 3 #}
25682558
```
25692559
2570-
#### `object_values(object)`
2560+
#### `object_values(object)` / `| object_values`
25712561
25722562
Get all values from an object as an array.
25732563
@@ -2578,30 +2568,27 @@ Get all values from an object as an array.
25782568
25792569
**Examples:**
25802570
```jinja
2581-
{# Get all values #}
2571+
{# Function syntax #}
25822572
{% set config = {"a": 1, "b": 2, "c": 3} %}
25832573
{% set values = object_values(object=config) %}
25842574
{{ to_json(object=values) }}
25852575
{# Output: [1,2,3] #}
25862576
2587-
{# Process all values #}
2577+
{# Filter syntax #}
25882578
{% set ports = {"http": 80, "https": 443, "app": 8080} %}
2589-
Open ports:
2590-
{% for port in object_values(object=ports) %}
2579+
{% for port in ports | object_values %}
25912580
- {{ port }}
25922581
{% endfor %}
25932582
{# Output:
2594-
Open ports:
25952583
- 80
25962584
- 443
25972585
- 8080
25982586
#}
25992587
2600-
{# Mixed type values #}
2601-
{% set config = {"str": "hello", "num": 42, "bool": true} %}
2602-
{% for value in object_values(object=config) %}
2603-
Value: {{ value }} (type: {{ type_of(value=value) }})
2604-
{% endfor %}
2588+
{# Chaining filters #}
2589+
{% set scores = {"alice": 95, "bob": 87, "charlie": 92} %}
2590+
Average: {{ scores | object_values | array_avg }}
2591+
{# Output: Average: 91.33... #}
26052592
```
26062593
26072594
#### `object_has_key(object, key)`
@@ -2793,7 +2780,7 @@ Rename object keys using a mapping.
27932780
{% set api_data = object_rename_keys(object=response, mapping={"userId": "user_id", "createdAt": "created_at"}) %}
27942781
```
27952782
2796-
#### `object_flatten(object, delimiter)`
2783+
#### `object_flatten(object, delimiter)` / `| object_flatten`
27972784
27982785
Flatten a nested object to dot-notation keys.
27992786
@@ -2804,22 +2791,25 @@ Flatten a nested object to dot-notation keys.
28042791
**Returns:** A flat object with delimited keys
28052792
28062793
```jinja
2794+
{# Function syntax #}
28072795
{% set nested = {"server": {"host": "localhost", "port": 8080}, "database": {"name": "mydb"}} %}
2808-
2809-
{# Default dot delimiter #}
28102796
{% set flat = object_flatten(object=nested) %}
28112797
{{ flat | tojson }}
28122798
{# Output: {"server.host":"localhost","server.port":8080,"database.name":"mydb"} #}
28132799
2814-
{# Custom delimiter #}
2815-
{% set flat_underscore = object_flatten(object=nested, delimiter="_") %}
2816-
{{ flat_underscore | tojson }}
2817-
{# Output: {"server_host":"localhost","server_port":8080,"database_name":"mydb"} #}
2800+
{# Filter syntax #}
2801+
{% set flat = nested | object_flatten %}
2802+
{{ flat["server.host"] }}
2803+
{# Output: localhost #}
28182804
2819-
{# Useful for environment variable generation #}
2820-
{% for key, value in object_flatten(object=config, delimiter="_") %}
2821-
export {{ key | upper }}="{{ value }}"
2822-
{% endfor %}
2805+
{# Filter syntax with delimiter #}
2806+
{% set flat_underscore = nested | object_flatten(delimiter="_") %}
2807+
{{ flat_underscore["server_host"] }}
2808+
{# Output: localhost #}
2809+
2810+
{# Chaining - get all flattened keys #}
2811+
{{ nested | object_flatten | object_keys | join(sep=", ") }}
2812+
{# Output: server.host, server.port, database.name #}
28232813
```
28242814
28252815
#### `object_unflatten(object, delimiter)`

REFACTOR.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -649,22 +649,24 @@ These should NOT become filters (they require context, have side effects, or are
649649

650650
**Commit:** e80aace
651651

652-
### Phase 11: Object Functions
652+
### Phase 11: Object Functions
653653

654-
**Category:** `object.rs`
654+
**Category:** `filter_functions/object.rs`
655655

656656
| Function | Filter | Status |
657657
|----------|--------|--------|
658-
| `object_keys` | `object_keys` | [ ] |
659-
| `object_values` | `object_values` | [ ] |
660-
| `object_flatten` | `object_flatten` | [ ] |
658+
| `object_keys` | `object_keys` | [x] |
659+
| `object_values` | `object_values` | [x] |
660+
| `object_flatten` | `object_flatten` | [x] |
661661

662-
- [ ] Migrate implementations
663-
- [ ] Update unit tests
664-
- [ ] Update integration tests to test filter syntax
665-
- [ ] Update README.md
666-
- [ ] Run `cargo make qa`
667-
- [ ] Update REFACTOR.md with current state
662+
- [x] Migrate implementations to `src/filter_functions/object.rs`
663+
- [x] Update unit tests (existing tests still pass)
664+
- [x] Update integration tests to test filter syntax (6 new tests)
665+
- [x] Update README.md with both syntaxes
666+
- [x] Run `cargo make qa`
667+
- [x] Update REFACTOR.md with current state
668+
669+
**Commit:** (pending)
668670

669671
### Phase 12: Kubernetes Functions
670672

src/filter_functions/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub mod datetime;
3131
pub mod encoding;
3232
pub mod hash;
3333
pub mod math;
34+
pub mod object;
3435
pub mod path;
3536
pub mod serialization;
3637
pub mod string;
@@ -126,4 +127,9 @@ pub fn register_all(env: &mut Environment) {
126127
url::UrlEncode::register(env);
127128
url::UrlDecode::register(env);
128129
url::ParseUrl::register(env);
130+
131+
// Phase 11: Object functions
132+
object::ObjectKeys::register(env);
133+
object::ObjectValues::register(env);
134+
object::ObjectFlatten::register(env);
129135
}

0 commit comments

Comments
 (0)