using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
///
/// Provides a JSON converter for that handles both array and single object representations.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class SingleItemOrListConverter : JsonConverter>
where T : class
{
///
public override IList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
if (reader.TokenType == JsonTokenType.StartArray)
{
List list = [];
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
if (JsonSerializer.Deserialize(ref reader, options.GetTypeInfo(typeof(T))) is T item)
{
list.Add(item);
}
}
return list;
}
if (reader.TokenType == JsonTokenType.StartObject)
{
return JsonSerializer.Deserialize(ref reader, options.GetTypeInfo(typeof(T))) is T item ? [item] : [];
}
throw new JsonException($"Unexpected token type: {reader.TokenType}. Expected StartArray or StartObject.");
}
///
public override void Write(Utf8JsonWriter writer, IList value, JsonSerializerOptions options)
{
switch (value)
{
case null:
writer.WriteNullValue();
return;
case { Count: 1 }:
JsonSerializer.Serialize(writer, value[0], options.GetTypeInfo(typeof(object)));
return;
default:
writer.WriteStartArray();
foreach (var item in value)
{
JsonSerializer.Serialize(writer, item, options.GetTypeInfo(typeof(object)));
}
writer.WriteEndArray();
return;
}
}
}