using System; using System.Collections.Generic; using Json.Schema; namespace Questionable.Validation; internal static class SchemaValidationHelper { internal readonly record struct ParsedError(string InstancePath, string PropertyPath, string Message); public static void CollectLeafErrors(EvaluationResults node, List errors) { if (!node.IsValid) { Dictionary errors2 = node.Errors; if (errors2 != null && errors2.Count > 0) { foreach (var (keyword, text3) in node.Errors) { if (!IsAggregateKeyword(keyword) && !string.IsNullOrWhiteSpace(text3)) { string text4 = node.InstanceLocation.ToString(); string rawPath = GetRawPath(text4); errors.Add(new ParsedError(text4 ?? string.Empty, FormatPath(rawPath), CleanMessage(text3))); } } } } List details = node.Details; if (details == null || details.Count <= 0) { return; } foreach (EvaluationResults detail in node.Details) { if (!detail.IsValid) { CollectLeafErrors(detail, errors); } } } public static string FormatPath(string rawPath) { if (string.IsNullOrEmpty(rawPath)) { return string.Empty; } string[] array = rawPath.Split('/'); List list = new List(); string[] array2 = array; foreach (string text in array2) { if (int.TryParse(text, out var result)) { if (list.Count > 0) { list[list.Count - 1] += $"[{result}]"; } else { list.Add($"[{result}]"); } } else { list.Add(text); } } return string.Join(".", list); } public static string CleanMessage(string message) { return message.Replace("\\u0022", "\"", StringComparison.Ordinal).Replace("\\u0027", "'", StringComparison.Ordinal); } public static string? FormatQuestLocation(byte? sequence, int? step) { if (!sequence.HasValue) { return null; } if (!step.HasValue) { return $"Seq {sequence}"; } return $"Seq {sequence}, Step {step}"; } private static bool IsAggregateKeyword(string keyword) { switch (keyword) { case "oneOf": case "allOf": case "anyOf": case "else": case "then": case "if": case "not": case "prefixItems": case "contains": return true; default: return false; } } private static string GetRawPath(string? instancePath) { if (string.IsNullOrEmpty(instancePath)) { return string.Empty; } if (instancePath.StartsWith('#')) { instancePath = instancePath.Substring(1); } if (instancePath.StartsWith('/')) { instancePath = instancePath.Substring(1); } return instancePath; } }