Skip to content

Add temporal range types and reusable options groups#6

Merged
carldebilly merged 3 commits intomainfrom
dev/cdb/options-group
Mar 4, 2026
Merged

Add temporal range types and reusable options groups#6
carldebilly merged 3 commits intomainfrom
dev/cdb/options-group

Conversation

@carldebilly
Copy link
Member

Why

Two recurring pain points when building CLI apps with Repl Toolkit:

  1. Repeated option sets — commands that share the same options (output format, verbosity, pagination…) force developers to duplicate parameters on every handler. This is error-prone and makes it hard to keep option names and aliases consistent across commands.

  2. Date/time intervals — querying logs, generating reports, or filtering audit trails almost always requires a "from/to" range. Today this means two separate parameters, manual validation that to >= from, and no compact syntax for "start + duration" patterns.

What changed

Reusable options groups ([ReplOptionsGroup])

A class decorated with [ReplOptionsGroup] can now be used directly as a handler parameter. Its public writable properties are expanded into individual command options, exactly as if they were declared on the handler itself.

[ReplOptionsGroup]
public class OutputOptions
{
    [ReplOption(Aliases = ["-f"])]
    public string Format { get; set; } = "text";

    [ReplOption(ReverseAliases = ["--no-verbose"])]
    public bool Verbose { get; set; }
}

app.Map("list", (OutputOptions output, int limit) => ...);
app.Map("show", (OutputOptions output, string id) => ...);
  • PascalCase properties are automatically lowered to camelCase tokens (Format--format)
  • All parameter attributes ([ReplOption], [ReplArgument], [ReplValueAlias]) work on properties
  • Property initializer values serve as defaults
  • Help text generation fully supports group properties (descriptions, defaults, placeholders)
  • Name collisions between group properties and regular parameters are detected at registration
  • Nested groups and abstract/interface types are rejected with clear error messages

Temporal range types

Three new record types represent date/time intervals: ReplDateRange, ReplDateTimeRange, and ReplDateTimeOffsetRange. They support two compact literal syntaxes:

  • Range: 2024-01-15..2024-02-15
  • Duration: 2024-01-15@30d
app.Map("report", (ReplDateRange period) =>
    $"{period.From:yyyy-MM-dd} to {period.To:yyyy-MM-dd}");

Reversed ranges (To < From) produce a validation error. Duration syntax reuses the existing TimeSpanLiteralParser.

Introduce ReplDateRange, ReplDateTimeRange, and ReplDateTimeOffsetRange
as first-class parameter types with two literal syntaxes: range (start..end)
and duration (start@duration). Parser uses ReadOnlySpan<char> internally
to minimize string allocations during split operations.
Introduce ReplOptionsGroupAttribute to mark classes whose public writable
properties expand into individual command options. Property names are
auto-lowered from PascalCase to camelCase for canonical tokens. Groups
support aliases, reverse aliases, value aliases, and all existing option
attributes on properties. Name collisions are detected at registration.

Also adds documentation for both options groups and temporal ranges,
and friendly type names for range types in help/docs output.
@carldebilly carldebilly merged commit 520cd0f into main Mar 4, 2026
10 checks passed
@carldebilly carldebilly deleted the dev/cdb/options-group branch March 4, 2026 03:24
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