Skip to content

Fix parameter substitution when both {p} and {p:format} appear#292

Merged
daniel-thom merged 2 commits intomainfrom
fix/parameterization
Apr 28, 2026
Merged

Fix parameter substitution when both {p} and {p:format} appear#292
daniel-thom merged 2 commits intomainfrom
fix/parameterization

Conversation

@daniel-thom
Copy link
Copy Markdown
Collaborator

substitute_parameters and substitute_parameters_regex used if let Some(...) { ... continue; } for the {p:format} branch, which meant that whenever a parameter had a format-spec occurrence, the simple {p} occurrences were never substituted. Templates mixing both forms (e.g., run.sh {w} 2024-{w:02d}-01) silently kept the bare {w} literal in the rendered output.

Replace the conditional with a while let Some(...) loop and remove the continue so both forms are handled, and so multiple distinct format specs for the same parameter (e.g., {i:02d} and {i:03d}) are all substituted.

substitute_parameters and substitute_parameters_regex used `if let
Some(...) { ... continue; }` for the {p:format} branch, which meant
that whenever a parameter had a format-spec occurrence, the simple
`{p}` occurrences were never substituted. Templates mixing both forms
(e.g., `run.sh {w} 2024-{w:02d}-01`) silently kept the bare `{w}`
literal in the rendered output.

Replace the conditional with a `while let Some(...)` loop and remove
the `continue` so both forms are handled, and so multiple distinct
format specs for the same parameter (e.g., `{i:02d}` and `{i:03d}`)
are all substituted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes template parameter expansion so {p} placeholders are still substituted even when {p:format} is present, and ensures multiple distinct format specs for the same parameter are handled.

Changes:

  • Update substitute_parameters / substitute_parameters_regex to replace all {param:format} occurrences before replacing {param}.
  • Add regression tests covering mixed {p} + {p:format}, multiple distinct specs, and regex-escaped substitutions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/client/parameter_expansion.rs Outdated
Comment thread src/client/parameter_expansion.rs Outdated
…plate syntax

The previous fix used `result.replace(&full_pattern, &replacement)` inside
a `while let Some(...) = result.find(&pattern)` loop. For String parameters,
`ParameterValue::format(Some(_))` ignores the format spec and returns the
raw value, so a String param whose value contains `{param_name:...}` would
cause `replace` to be a no-op and `find` to keep returning the same index
— spinning forever.

Switch to a cursor-based scan with `replace_range`, so the loop only ever
inspects bytes that have not yet been substituted. This guarantees
termination regardless of what a parameter value contains. Added a
regression test that hangs without the fix.

Reported by Copilot on PR #292.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a bug in template parameter expansion where the presence of a {p:format} occurrence prevented substitution of bare {p} occurrences for the same parameter. This improves correctness for mixed-form templates and ensures multiple distinct format specs for the same parameter are all substituted.

Changes:

  • Reworked {param:format} substitution to iterate through all occurrences using a cursor-based scan (avoids re-scanning substituted text and supports multiple format specs).
  • Ensured {param} substitution always runs even when {param:format} was present.
  • Added regression tests covering mixed {p} + {p:format}, multiple format specs, termination when values contain template-like text, and the regex-escaping variant.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@daniel-thom daniel-thom merged commit 95d9532 into main Apr 28, 2026
13 checks passed
@daniel-thom daniel-thom deleted the fix/parameterization branch April 28, 2026 23:59
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.

2 participants