using Shogi.Contracts.Types; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text.RegularExpressions; namespace Shogi.Contracts.Api; public class MovePieceCommand : IValidatableObject { /// /// Mutually exclusive with . /// Set this property to indicate moving a piece from the hand onto the board. /// public WhichPiece? PieceFromHand { get; set; } /// /// Board position notation, like A3 or G1 /// Mutually exclusive with . /// Set this property to indicate moving a piece from the board to another position on the board. /// public string? From { get; set; } /// /// Board position notation, like A3 or G1 /// [Required] public string To { get; set; } public bool IsPromotion { get; set; } public IEnumerable Validate(ValidationContext validationContext) { if (PieceFromHand.HasValue && !string.IsNullOrWhiteSpace(From)) { yield return new ValidationResult($"{nameof(PieceFromHand)} and {nameof(From)} are mutually exclusive properties."); } if (!Regex.IsMatch(To, "[A-I][1-9]")) { yield return new ValidationResult($"{nameof(To)} must be a valid board position, between A1 and I9"); } if (!string.IsNullOrEmpty(From) && !Regex.IsMatch(From, "[A-I][1-9]")) { yield return new ValidationResult($"{nameof(From)} must be a valid board position, between A1 and I9"); } } }