Skip to content

Add tree-shaped parameter loader mirroring Python (#50)#84

Open
vahid-ahmadi wants to merge 1 commit into
mainfrom
vahid/parameter-tree-loader
Open

Add tree-shaped parameter loader mirroring Python (#50)#84
vahid-ahmadi wants to merge 1 commit into
mainfrom
vahid/parameter-tree-loader

Conversation

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Addresses #50.

Scope

Lands a tree-shaped parameter loader (ParamTree) that mirrors the Python policyengine-uk directory-tree parameter system. This is additive: it does not delete the existing flat year-files (parameters/YYYY_YY.yaml) or the hand-coded Parameters struct, and it does not change any existing consumer. The new loader coexists with the existing system so nothing breaks and everything still compiles.

New module src/parameters/param_tree.rs:

  • ParamTree::from_dir walks a directory tree of YAML parameter files and parses each leaf into a typed Node tree. Directories become interior Subtree nodes; .yaml/.yml files become leaves keyed by file stem.
  • Supports the three Python parameter node types:
    • values: — date-keyed scalars
    • brackets: — list of { rate, threshold }, each date-keyed
    • scales: — synonym for brackets:, handled identically
  • Path resolution mirrors Python: tree.get_at("gov.hmrc.income_tax.rates.basic_rate", 2025) returns the value in force at that date, using step-function semantics (latest entry on or before the requested date). null entries clear a value within a window.
  • Forward auto-uprating: a value requested beyond its last declared year is projected forward using the index declared in metadata.uprating (e.g. gov.indices.cpi), scaling the last-known value by index(requested) / index(base). With no index the series is held flat.
  • A small fixture parameter tree under tests/fixtures/parameters/gov/ (income tax rates/personal allowance, UC standard allowance, Scottish LBTT brackets, CPI index) gives the loader real YAML to parse.

Tests

8 unit tests covering: value-by-date resolution (including before-first-entry → None), the step-function picking the latest on-or-before entry, directory path lookup, bracket/scale parsing and resolution, forward uprating projection beyond the last declared year, holding flat without an index, the scales: synonym, and null-within-window clearing.

cargo build and cargo test both pass (198 existing tests + 8 new, 0 failures).

Remaining

This PR lands the loader infrastructure only. Migrating the compute_* consumers in src/variables/ off the hand-coded Parameters struct onto path-keyed ParamTree lookups (and copying the authoritative gov/... tree from policyengine-uk) is the follow-up for #50 — out of scope here because it would touch every consumer at once.

🤖 Generated with Claude Code

Add `ParamTree`, a directory-tree parameter loader that mirrors the
Python policyengine-uk parameter system, landing additively alongside
the existing hand-coded `Parameters` struct and flat year-files.

- Walks a directory tree of YAML files into a typed node tree.
- Supports the three Python node types: `values:` (date-keyed scalars),
  `brackets:`, and `scales:` (handled as brackets).
- Path resolution by dot-separated path with Python step-function date
  semantics (latest value on or before the requested date; `null`
  clears a window).
- Forward auto-uprating: values beyond the last declared year are
  projected by an index from `metadata.uprating`, scaling the last
  known value by index(now)/index(base); holds flat without an index.
- Adds a small fixture parameter tree under tests/fixtures/parameters/
  and tests covering value-by-date resolution, bracket/scale parsing,
  path lookup, and uprating projection.

Migrating compute_* consumers off the hand-coded struct is the
remaining follow-up for #50.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant