Skip to content

refactor(binder): extract shared list-element iteration - #184

Merged
Reefact merged 1 commit into
mainfrom
150-dedupe-converter-loops
Jul 18, 2026
Merged

refactor(binder): extract shared list-element iteration#184
Reefact merged 1 commit into
mainfrom
150-dedupe-converter-loops

Conversation

@Reefact

@Reefact Reefact commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

The three list converters each carried an identical element loop. This factors that shared iteration into a single internal RequestBinder.ConvertEachElement primitive, so the loop and the null-element rule live in one place. No behavior change, no public API change.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Analyzer / diagnostic change
  • Tests
  • Documentation
  • Build / CI / tooling

Changes

  • Add internal RequestBinder<TRequest>.ConvertEachElement<TStored, TProperty>(...): indexed iteration over the stored list elements, a null element recorded as REQUEST_ARGUMENT_REQUIRED, every successful element collected (one bad element never hides the others), and the bound RequiredField returned. It is generic over the stored element type (TStored) so element is null narrows uniformly for both reference elements and Nullable<T> elements — avoiding the type-kind wall that forced the value-type list converter to be separate.
  • ListOfSimplePropertiesConverter.ConvertElements now delegates to the primitive, supplying only its per-element convert + RecordArgumentInvalid.
  • ListOfSimpleValuePropertiesConverter.ConvertElements likewise, supplying the Nullable<T> unwrap (element.Value) + RecordArgumentInvalid.
  • ListOfComplexPropertiesConverter.BindElements likewise, supplying the nested binder + NestedFailure.Group wrapping.

Net effect: the triplicated iteration/index/null-element/collect logic is removed (+52 / −70).

Testing

  • dotnet build FirstClassErrors.sln — 0 warnings, 0 errors
  • dotnet test FirstClassErrors.sln — 1000 tests, 0 failures
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests)

Documentation

  • No documentation change required

Architecture decisions

  • No architectural decision in this pull request

Related issues

Closes #150


Generated by Claude Code

The three list converters (simple, simple-value, complex) each carried an
identical element loop: indexed iteration, a null element recorded as
REQUEST_ARGUMENT_REQUIRED, collect every successful element, and return a
RequiredField. Factor that shared invariant into a single
RequestBinder.ConvertEachElement primitive so the iteration and the
null-element rule live in one place; each converter now supplies only its
per-element convert/bind and failure recording through a callback.

No behavior change; the public binder surface is unchanged.

Refs: #150

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J12ghrzM1xiAKw4LETJDqr
@Reefact
Reefact merged commit 3f3475b into main Jul 18, 2026
13 checks passed
@Reefact
Reefact deleted the 150-dedupe-converter-loops branch July 18, 2026 14:00
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.

Binder: factor out the duplicated missing / element-loop / wrapping logic across converters

2 participants