using System.ComponentModel.DataAnnotations;
namespace StabilityMatrix.Core.Validators;
///
/// Validator that requires equality to another property
/// i.e. Confirm password must match password
///
public sealed class RequiresMatchAttribute : ValidationAttribute
where T : IEquatable
{
public string PropertyName { get; }
public RequiresMatchAttribute(string propertyName)
{
PropertyName = propertyName;
}
public RequiresMatchAttribute(string propertyName, string errorMessage)
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
}
protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var otherProperty =
instance.GetType().GetProperty(PropertyName)
?? throw new ArgumentException($"Property {PropertyName} not found");
if (otherProperty.PropertyType != typeof(T))
{
throw new ArgumentException($"Property {PropertyName} is not of type {typeof(T)}");
}
var otherValue = otherProperty.GetValue(instance);
if (otherValue == null && value == null)
{
return ValidationResult.Success!;
}
if (((IEquatable?)otherValue)!.Equals(value))
{
return ValidationResult.Success!;
}
return new ValidationResult(
$"{validationContext.DisplayName} does not match {PropertyName}"
);
}
}