Skip to content

feat: SelfValidator for custom and cross-field validation#25

Open
mlwelles wants to merge 1 commit into
matthewmcneely:mainfrom
mlwelles:feature/self-validation
Open

feat: SelfValidator for custom and cross-field validation#25
mlwelles wants to merge 1 commit into
matthewmcneely:mainfrom
mlwelles:feature/self-validation

Conversation

@mlwelles

@mlwelles mlwelles commented Jun 4, 2026

Copy link
Copy Markdown

Adds SelfValidator, an opt-in seam that lets a type drive its own validation — building on the existing StructValidator support rather than replacing it.

What

  • New interface SelfValidator { ValidateWith(ctx, v StructValidator) error }.
  • When a value passed to Insert/Upsert/Update implements SelfValidator, the client calls ValidateWith instead of handing it straight to the configured StructValidator.
  • validateStruct routes each element through a new validateOne helper that detects SelfValidator (on the value or its address) and otherwise falls back to StructCtxunchanged behavior for ordinary structs.

Why

Struct tags handle field-at-a-time checks, but plenty of validation lives outside what tags can express. SelfValidator is the seam for that:

  • Cross-field rules — one field constrained by another (e.g. End >= Start, password == confirm).
  • Conditional rules — field B required only when field A has some value.
  • Computed / setter-derived values — validate state that isn't a plain tagged field.
  • Business rules — anything that needs real logic.

ValidateWith receives the configured StructValidator, so an implementation can still run ordinary tag-based validation and layer custom logic on top.

Tests

TestValidateRoutesToSelfValidator, TestValidateFallsBackToStructCtx, TestValidateSelfValidatorInSlice, and TestSelfValidatorCustomCrossFieldRule (a concrete cross-field example) cover the routing, the unchanged fallback, and the custom-rule utility.

@mlwelles mlwelles requested a review from matthewmcneely as a code owner June 4, 2026 20:14

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

Adds SelfValidator, an opt-in seam that lets a type drive its own
validation. When a value passed to Insert, Upsert, or Update implements
SelfValidator, the client calls ValidateWith instead of handing the value
straight to the configured StructValidator.

This covers validation that struct tags cannot express on their own:
cross-field rules (one field constrained by another), conditional rules,
checks on computed or setter-derived values, and broader business rules.
ValidateWith receives the configured StructValidator, so an implementation
can still run ordinary tag-based checks and layer custom logic on top.

validateStruct routes each element through a new validateOne helper that
detects SelfValidator (on the value or its address) and otherwise falls back
to StructCtx exactly as before — behavior is unchanged for ordinary structs.
@mlwelles mlwelles force-pushed the feature/self-validation branch from 501b3ef to 504231c Compare June 4, 2026 20:45
@mlwelles mlwelles changed the title feat: SelfValidator for private-field validation feat: SelfValidator for custom and cross-field validation Jun 4, 2026
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