facet_generate 0.17.1

Generate Swift, Kotlin, TypeScript, and C# from types annotated with `#[derive(Facet)]`
Documentation
using System;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;

using Facet.Runtime.Serde;

namespace Facet.Runtime.Json;

public static class JsonSerde
{
    internal static readonly JsonSerializerOptions Options = new()
    {
        Converters =
        {
            new JsonStringEnumConverter(),
            new ObservableCollectionJsonConverterFactory()
        }
    };

    public static string Serialize<T>(T value)
    {
        if (value is null)
        {
            throw new ArgumentNullException(nameof(value));
        }

        return JsonSerializer.Serialize(value, Options);
    }

    public static T Deserialize<T>(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
        {
            throw new DeserializationError("Cannot deserialize empty input");
        }

        var value = JsonSerializer.Deserialize<T>(input, Options);
        if (value is null)
        {
            throw new DeserializationError($"Deserialization produced null for {typeof(T).Name}");
        }

        return value;
    }
}

internal sealed class ObservableCollectionJsonConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeToConvert.IsGenericType &&
               typeToConvert.GetGenericTypeDefinition() == typeof(ObservableCollection<>);
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        var elementType = typeToConvert.GetGenericArguments()[0];
        var converterType = typeof(ObservableCollectionJsonConverter<>).MakeGenericType(elementType);
        return (JsonConverter)Activator.CreateInstance(converterType)!;
    }

    private sealed class ObservableCollectionJsonConverter<T> : JsonConverter<ObservableCollection<T>>
    {
        public override ObservableCollection<T> Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            var list = JsonSerializer.Deserialize<List<T>>(ref reader, options)
                ?? throw new DeserializationError("Failed to deserialize collection");
            return new ObservableCollection<T>(list);
        }

        public override void Write(
            Utf8JsonWriter writer,
            ObservableCollection<T> value,
            JsonSerializerOptions options)
        {
            JsonSerializer.Serialize(writer, (IEnumerable<T>)value, options);
        }
    }
}