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; } } }