Skip to content

[FEATURE] Add Guards.TryValidateZero<T> ROP guard clause #656

@dlrivada

Description

@dlrivada

Summary

Add Guards.TryValidateZero<T> to Encina.GuardClauses to provide an ROP-compatible equivalent of .NET 8's ArgumentOutOfRangeException.ThrowIfZero<T>.

Motivation

.NET 8 introduced ArgumentOutOfRangeException.ThrowIfZero<T>() which validates that a value is not zero. This is exception-based and incompatible with Encina's ROP pattern.

Priority: Medium

Use Cases

  • Validating divisors before division operations (avoid divide-by-zero in domain logic)
  • Validating pricing multipliers (zero multiplier would zero out all prices)
  • Validating scaling factors in calculations

Proposed Solution

/// <summary>
/// Validates that a value is not zero.
/// </summary>
public static bool TryValidateZero<T>(
    T value,
    string paramName,
    out EncinaError error,
    string? message = null)
    where T : IComparable<T>

Usage Example

if (!Guards.TryValidateZero(divisor, nameof(divisor), out var error,
    message: "Divisor cannot be zero"))
    return Left<EncinaError, decimal>(error);

Alternatives Considered

  1. Use TryValidate(value != 0, ...): Works but loses semantic metadata.
  2. Use TryValidatePositive or TryValidateNegative: Only covers half the valid values.

Affected Packages

  • Encina.GuardClauses

Test Matrix

Test Type Required? Scope Notes
UnitTests Required Zero, positive, negative values, custom messages
GuardTests Required Null parameter checks
PropertyTests Recommended Invariant: returns false iff value == 0

Implementation Tasks

  • Add Guards.TryValidateZero<T> method to Guards.cs
  • Add XML documentation with examples
  • Add unit tests
  • Add guard clause tests
  • Add property-based tests
  • Update README.md
  • Update PublicAPI.Unshipped.txt

Acceptance Criteria

  • Method returns false when value equals zero
  • Metadata includes guard type (Zero), parameter name, actual value, type
  • Custom message support
  • Comprehensive unit tests
  • XML doc comments

.NET Equivalent

ArgumentOutOfRangeException.ThrowIfZero<T>(T value, string? paramName) (since .NET 8)

Related Issues

Part of ROP guard clause parity with .NET 8-10 built-in throw helpers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-domain-modelingDomain modeling building blocks (Entities, Value Objects, Aggregates)area-validationValidation patterns and providersdotnet-10Leverages .NET 10 new featuresenhancementNew feature or requestpriority-mediumPriority: Medium (⭐⭐⭐)

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions