// This file is auto-generated by alef. DO NOT EDIT.
#nullable enable

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace {{ namespace }};
{% if doc -%}

/// <summary>
{%- for line in doc_lines %}
/// {{ line }}
{%- endfor %}
/// </summary>
{%- endif %}

/// <summary>
/// Transparent wrapper for an untagged Rust union (`#[serde(untagged)]`).
/// Holds the raw JSON shape so the Rust core can resolve the variant on the
/// way in. Use `Of(...)` / `FromJson(...)` to construct, and the `As*()`
/// probes to inspect on the way out.
/// </summary>
[JsonConverter(typeof({{ class_name }}JsonConverter))]
public sealed class {{ class_name }} : IEquatable<{{ class_name }}>
{
    public JsonElement Value { get; }

    public {{ class_name }}(JsonElement value)
    {
        // Clone the JsonElement into an owned document so the wrapper outlives
        // the JsonReader/JsonDocument that produced the element.
        Value = value.ValueKind == JsonValueKind.Undefined
            ? value
            : JsonDocument.Parse(value.GetRawText()).RootElement.Clone();
    }

    public static {{ class_name }} Of(string s)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(s));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} Of(IEnumerable<string> items)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(items));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} OfObject(object o)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(o));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} FromJson(string json)
    {
        using var doc = JsonDocument.Parse(json);
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public string? AsString() =>
        Value.ValueKind == JsonValueKind.String ? Value.GetString() : null;

    public List<string>? AsList()
    {
        if (Value.ValueKind != JsonValueKind.Array) return null;
        var result = new List<string>(Value.GetArrayLength());
        foreach (var element in Value.EnumerateArray())
        {
            result.Add(element.ToString());
        }
        return result;
    }

    public JsonElement? AsObject() =>
        Value.ValueKind == JsonValueKind.Object ? Value : null;

    public bool Equals({{ class_name }}? other) =>
        other is not null && Value.GetRawText() == other.Value.GetRawText();

    public override bool Equals(object? obj) => Equals(obj as {{ class_name }});

    public override int GetHashCode() => Value.GetRawText().GetHashCode();

    public override string ToString() => Value.GetRawText();
}

internal sealed class {{ class_name }}JsonConverter : JsonConverter<{{ class_name }}>
{
    public override {{ class_name }} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public override void Write(Utf8JsonWriter writer, {{ class_name }} value, JsonSerializerOptions options)
    {
        value.Value.WriteTo(writer);
    }
}
