using System.Text.Json.Serialization; namespace StitchATon2.App.Models; public class GenerateImageDto { [JsonPropertyName("canvas_rect")] public string? CanvasRect { get; set; } [JsonPropertyName("crop_offset")] public float[]? CropOffset { get; set; } [JsonPropertyName("crop_size")] public float[]? CropSize { get; set; } [JsonPropertyName("output_scale")] public float? OutputScale { get; set; } public Dictionary> GetErrors() { return ValidateCanvasRect() .Concat(ValidateNumberPair(CropOffset, "crop_offset")) .Concat(ValidateNumberPair(CropSize, "crop_size")) .Concat(ValidateNumber(OutputScale, "output_scale")) .GroupBy(item => item.Item1) .ToDictionary(item => item.Key, item => item.Select(p => p.Item2).ToList()); } private IEnumerable<(string, string)> ValidateCanvasRect() { if (string.IsNullOrEmpty(CanvasRect)) { yield return ("canvas_rect", "canvas_rect is required."); } } private IEnumerable<(string, string)> ValidateNumberPair(float[]? numberPair, string fieldName) { if (numberPair is null) { yield return (fieldName, $"{fieldName} is required."); } else if (numberPair.Length != 2) { yield return (fieldName, $"{fieldName} must have exactly 2 elements."); } else { foreach (var item in ValidateNumber(numberPair[0], $"{fieldName}[0]")) yield return item; foreach (var item in ValidateNumber(numberPair[1], $"{fieldName}[1]")) yield return item; } } private IEnumerable<(string, string)> ValidateNumber(float? number, string fieldName, double min = 0.0, double max = 1.0) { if (number is null) { yield return (fieldName, $"{fieldName} is required."); } else if (number < min) { yield return (fieldName, $"{fieldName} must be greater than or equal to {min}."); } else if (number > max) { yield return (fieldName, $"{fieldName} must be less than or equal to {max}."); } } public override string ToString() { return $"CoordinatePair: {CanvasRect}, Crop: [{CropOffset![0]} {CropOffset[1]} {CropSize![0]} {CropSize[1]}], OutputScale: {OutputScale}"; } }