48 lines
1.9 KiB
C#
48 lines
1.9 KiB
C#
using System.Collections.Concurrent;
|
|||
|
|
using System.Text.Json;
|
||
|
|
using System.Text.Json.Serialization;
|
||
|
|
using System.Text.Json.Serialization.Metadata;
|
||
|
|
|
||
|
|
using decePubClient.Models.Mastodon;
|
||
|
|
|
||
|
|
using PrivaPub.ClientModels;
|
||
|
|
|
||
|
|
namespace decePubClient.Helpers
|
||
|
|
{
|
||
|
|
public sealed class UnregisteredJson : IJsonTypeInfoResolver
|
||
|
|
{
|
||
|
|
public static readonly UnregisteredJson Instance = new();
|
||
|
|
static readonly DefaultJsonTypeInfoResolver Reflection = new();
|
||
|
|
static readonly ConcurrentDictionary<Type, byte> Reported = new();
|
||
|
|
|
||
|
|
public static bool Strict { get; set; }
|
||
|
|
|
||
|
|
public JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
|
||
|
|
{
|
||
|
|
if (Strict)
|
||
|
|
throw new NotSupportedException($"{type.FullName} is not registered in a JsonSerializerContext (HR0306).");
|
||
|
|
if (Reported.TryAdd(type, 0))
|
||
|
|
Console.Error.WriteLine($"{type.FullName} is serialized without a JsonSerializerContext registration (HR0306)");
|
||
|
|
return Reflection.GetTypeInfo(type, options);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Check(bool strict)
|
||
|
|
{
|
||
|
|
Strict = strict;
|
||
|
|
if (!strict)
|
||
|
|
return;
|
||
|
|
var missing = Missing(ClientModelsJsonContext.Default, typeof(WebResult), "PrivaPub.ClientModels")
|
||
|
|
.Concat(Missing(MastodonJsonContext.Default, typeof(Status), "decePubClient.Models.Mastodon"))
|
||
|
|
.ToList();
|
||
|
|
if (missing.Count > 0)
|
||
|
|
throw new InvalidOperationException("Not registered in a JsonSerializerContext (HR0306): " + string.Join(", ", missing));
|
||
|
|
}
|
||
|
|
|
||
|
|
static IEnumerable<string> Missing(IJsonTypeInfoResolver context, Type anchor, string space) =>
|
||
|
|
anchor.Assembly.GetTypes()
|
||
|
|
.Where(t => t.IsClass && t.IsPublic && !t.IsAbstract && !t.IsGenericTypeDefinition && t.Namespace is { } ns && ns.StartsWith(space, StringComparison.Ordinal)
|
||
|
|
&& !ns.EndsWith(".Resources", StringComparison.Ordinal) && !typeof(Attribute).IsAssignableFrom(t) && !typeof(JsonSerializerContext).IsAssignableFrom(t))
|
||
|
|
.Where(t => context.GetTypeInfo(t, new JsonSerializerOptions()) == null)
|
||
|
|
.Select(t => t.FullName);
|
||
|
|
}
|
||
|
|
}
|