feat: support default values in request templates - #31
Draft
mantono wants to merge 11 commits into
Draft
Conversation
Replace the plain-key-only regex scanner in src/templ.rs with a manual
scanner/parser that yields one Reference per occurrence, preserving the
byte span of each match. Supports plain {{NAME}}, static
{{NAME:value}}, and command {{NAME|command}} forms while keeping the
existing NAME rule ([A-Za-z0-9_-], 1-32 chars). Delimiter content after
the first ':' or '|' is treated literally up to the next "}}", so
additional ':'/'|' characters remain part of the fallback. Invalid,
unterminated, or non-name constructs are left as ordinary template
text, matching prior rendering behavior.
find_keys is now implemented on top of scan() and keeps its previous
signature and legacy discovery behavior, so src/template.rs is
unaffected by this change.
Adds parser tests for all three reference forms, literal ':'/'|'
retention in fallback content, repeated names with distinct
fallbacks, name-length boundaries, invalid/unterminated constructs,
and legacy key discovery.
…acks
Refactor substitution() in src/template.rs to resolve each parsed
Reference from templ::scan() individually rather than by distinct key
name only. For every occurrence, resolution now follows: a merged
property by NAME, then that occurrence's static fallback, then its
dynamic (command) result, then an interactive prompt only for a plain
missing occurrence, and finally SubstitutionError::MissingValue.
Extended (static/command) occurrences are rewritten to unique internal
Handlebars keys before strict-mode rendering, so distinct fallback
occurrences of the same NAME stay independent while a supplied value
still overrides every occurrence, including an empty sourced value.
Plain occurrences keep their original {{NAME}} text and shared vars
entry, preserving no_escape, strict-mode failure mapping, and existing
normal-template/legacy-missing-value behavior unchanged.
Command execution itself is out of scope for this task (task 3); a
resolve_dynamic() seam always reports unresolved for now, which
correctly falls through to MissingValue without prompting.
Adds tests for static fallback resolution, sourced-value override from
every Property::Source (including an empty override), per-occurrence
mixed/default values, suppression of interactive prompting by any
fallback occurrence, and legacy missing-value behavior.
Add Args::allow_command_fallbacks(), backed by the opt-in --allow-command-fallbacks flag, and thread it from main.rs into substitution(). Command-fallback resolution now returns a distinct SubstitutionError::CommandFallbackNotAllowed when reached without permission, instead of silently treating it as a missing value. Isolate shell invocation behind a small src/runner.rs adapter (sh -c on unix, cmd /C on windows) that normalizes stdout by removing only trailing CR/LF and surfaces launch failures, non-zero exit statuses, and non-UTF-8 stdout as distinct RunnerError variants. FireError mapping for the new SubstitutionError variants is intentionally minimal plumbing; a dedicated variant and exit code are added by a later task.
… variants Add FireError::CommandFallbackNotAllowed and FireError::CommandFallbackFailed(RunnerError), each with a distinct, secret-free Display message and a stable exit code (12 and 13, respectively, the next codes free after the existing 1 and 3-11). main.rs now maps SubstitutionError's two command-fallback variants directly to these, instead of collapsing them into the generic FireError::Other/TemplateRendering. Termination::report is refactored around a private exit_code() method so tests can assert on the underlying u8 without relying on ExitCode's opaque representation. Tests cover both new Display messages (including all three RunnerError sub-cases), document why 12/13 were chosen, and assert every FireError variant's exit code stays pairwise unique. RunnerError never carries resolved fallback values or command stdout, so these messages cannot leak secrets.
Document static and command defaults, source precedence, occurrence semantics, interactive ordering, command output behavior, platform shells, and the opt-in security warning. Add documentation-only example request files for both forms.
… test The test used printf's \xff hex escape to produce an invalid UTF-8 byte. Ubuntu's default /bin/sh (dash) does not support \xff and instead prints the literal bytes \xff, which is valid UTF-8, causing the test to fail on CI while passing locally under bash. Replace it with \377, a POSIX octal escape for 0xFF supported by both dash and bash, preserving the test's intent of exercising RunnerError::NonUtf8.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
{{NAME:value}}and opt-in dynamic{{NAME|command}}template defaultsCloses #30
Verification
cargo build --all-featurescargo testcargo clippy --all-targets --all-features -- -D warningsremains blocked by seven pre-existing warnings onmaster; no feature-caused Clippy findings.