102 lines
2.8 KiB
C#
102 lines
2.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
using Json.Schema;
|
|
|
|
namespace Questionable.Validation.Validators;
|
|
|
|
internal abstract class DefinitionSchemaValidator : IDefinitionSchemaValidator
|
|
{
|
|
protected const string BaseUri = "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main";
|
|
|
|
private readonly SchemaRegistrar _schemaRegistrar;
|
|
|
|
private readonly Dictionary<ushort, JsonNode> _nodes = new Dictionary<ushort, JsonNode>();
|
|
|
|
private JsonSchema? _schema;
|
|
|
|
protected abstract EPathType PathType { get; }
|
|
|
|
protected abstract string MainSchemaUri { get; }
|
|
|
|
protected DefinitionSchemaValidator(SchemaRegistrar schemaRegistrar)
|
|
{
|
|
_schemaRegistrar = schemaRegistrar;
|
|
}
|
|
|
|
public void Enqueue(ushort id, JsonNode node)
|
|
{
|
|
_nodes[id] = node;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_nodes.Clear();
|
|
}
|
|
|
|
public IEnumerable<ValidationIssue> Validate()
|
|
{
|
|
if (_nodes.Count == 0)
|
|
{
|
|
yield break;
|
|
}
|
|
if (_schema == null)
|
|
{
|
|
_schema = _schemaRegistrar.Get(MainSchemaUri);
|
|
}
|
|
foreach (var (id, node) in _nodes)
|
|
{
|
|
foreach (ValidationIssue item in ValidateImmediate(id, node))
|
|
{
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<ValidationIssue> ValidateImmediate(ushort id, JsonNode node)
|
|
{
|
|
if (_schema == null)
|
|
{
|
|
_schema = _schemaRegistrar.Get(MainSchemaUri);
|
|
}
|
|
EvaluationResults evaluationResults = _schema.Evaluate(JsonSerializer.SerializeToElement(node), new EvaluationOptions
|
|
{
|
|
Culture = CultureInfo.InvariantCulture,
|
|
OutputFormat = OutputFormat.Hierarchical
|
|
});
|
|
if (evaluationResults.IsValid)
|
|
{
|
|
return new List<ValidationIssue>();
|
|
}
|
|
List<SchemaValidationHelper.ParsedError> list = new List<SchemaValidationHelper.ParsedError>();
|
|
SchemaValidationHelper.CollectLeafErrors(evaluationResults, list);
|
|
if (list.Count == 0)
|
|
{
|
|
int num = 1;
|
|
List<ValidationIssue> list2 = new List<ValidationIssue>(num);
|
|
CollectionsMarshal.SetCount(list2, num);
|
|
CollectionsMarshal.AsSpan(list2)[0] = new ValidationIssue
|
|
{
|
|
PathType = PathType,
|
|
Id = id.ToString(CultureInfo.InvariantCulture),
|
|
Location = null,
|
|
Type = EIssueType.InvalidJsonSchema,
|
|
Severity = EIssueSeverity.Error,
|
|
Description = "JSON schema validation failed"
|
|
};
|
|
return list2;
|
|
}
|
|
return list.Select((SchemaValidationHelper.ParsedError error) => new ValidationIssue
|
|
{
|
|
PathType = PathType,
|
|
Id = id.ToString(CultureInfo.InvariantCulture),
|
|
Location = (string.IsNullOrEmpty(error.PropertyPath) ? null : error.PropertyPath),
|
|
Type = EIssueType.InvalidJsonSchema,
|
|
Severity = EIssueSeverity.Error,
|
|
Description = (string.IsNullOrEmpty(error.PropertyPath) ? error.Message : (error.PropertyPath + ": " + error.Message))
|
|
}).ToList();
|
|
}
|
|
}
|