Skip to content

Commit

Permalink
chore: add ListWithStringFallback converters and JSON roundtrip test
Browse files Browse the repository at this point in the history
  • Loading branch information
filzrev committed Oct 5, 2024
1 parent c75e397 commit 657b118
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 59 deletions.
3 changes: 2 additions & 1 deletion src/Docfx.App/Config/ListWithStringFallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace Docfx;
/// <summary>
/// ListWithStringFallback.
/// </summary>
[Newtonsoft.Json.JsonConverter(typeof(ListWithStringFallbackConverter))]
[Newtonsoft.Json.JsonConverter(typeof(ListWithStringFallbackConverter.NewtonsoftJsonConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(ListWithStringFallbackConverter.SystemTextJsonConverter))]
internal class ListWithStringFallback : List<string>
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Docfx;


internal partial class ListWithStringFallbackConverter
{
/// <summary>
/// JsonConverter for <see cref="ListWithStringFallback"/>.
/// </summary>
internal class NewtonsoftJsonConverter : JsonConverter
{
/// <inheritdoc/>
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FileMapping);
}

/// <inheritdoc/>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var model = new ListWithStringFallback();
var value = reader.Value;
IEnumerable<JToken> jItems;
if (reader.TokenType == JsonToken.StartArray)
{
jItems = JArray.Load(reader);
}
else if (reader.TokenType == JsonToken.StartObject)
{
jItems = JContainer.Load(reader);
}
else if (reader.TokenType == JsonToken.String)
{
jItems = JRaw.Load(reader);
}
else
{
jItems = JObject.Load(reader);
}

if (jItems is JValue)
{
model.Add(jItems.ToString());
}
else
{
foreach (var item in jItems)
{
model.Add(item.ToString());
}
}

return model;
}

/// <inheritdoc/>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartArray();
foreach (var item in (ListWithStringFallback)value)
{
serializer.Serialize(writer, item);
}
writer.WriteEndArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using YamlDotNet.Serialization;

namespace Docfx;


internal partial class ListWithStringFallbackConverter
{
/// <summary>
/// JsonConverter for <see cref="ListWithStringFallback"/>.
/// </summary>
internal class SystemTextJsonConverter : JsonConverter<ListWithStringFallback>
{
public override ListWithStringFallback Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var tokenType = reader.TokenType;
switch (tokenType)
{
case JsonTokenType.String:
{
var value = reader.GetString();
return new ListWithStringFallback([value]);
}
case JsonTokenType.StartArray:
{
var items = JsonSerializer.Deserialize<string[]>(ref reader, options);
return new ListWithStringFallback(items);
}
case JsonTokenType.StartObject:
{
using var document = JsonDocument.ParseValue(ref reader);
JsonElement root = document.RootElement;
var values = root.EnumerateObject().Select(x=>x.ToString());
return new ListWithStringFallback(values);
}
default:
throw new NotSupportedException($"TokenType({reader.TokenType}) is not supported.");
}
}

public override void Write(Utf8JsonWriter writer, ListWithStringFallback value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var item in value)
{
writer.WriteStringValue(item);
}
writer.WriteEndArray();
}
}
}
60 changes: 2 additions & 58 deletions src/Docfx.App/Config/ListWithStringFallbackConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,7 @@

namespace Docfx;

/// <summary>
/// JsonConverter for <see cref="ListWithStringFallback"/>.
/// </summary>
internal class ListWithStringFallbackConverter : JsonConverter
{
/// <inheritdoc/>
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FileMapping);
}

/// <inheritdoc/>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var model = new ListWithStringFallback();
var value = reader.Value;
IEnumerable<JToken> jItems;
if (reader.TokenType == JsonToken.StartArray)
{
jItems = JArray.Load(reader);
}
else if (reader.TokenType == JsonToken.StartObject)
{
jItems = JContainer.Load(reader);
}
else if (reader.TokenType == JsonToken.String)
{
jItems = JRaw.Load(reader);
}
else
{
jItems = JObject.Load(reader);
}

if (jItems is JValue)
{
model.Add(jItems.ToString());
}
else
{
foreach (var item in jItems)
{
model.Add(item.ToString());
}
}

return model;
}

/// <inheritdoc/>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartArray();
foreach (var item in (ListWithStringFallback)value)
{
serializer.Serialize(writer, item);
}
writer.WriteEndArray();
}
internal partial class ListWithStringFallbackConverter
{
}
1 change: 1 addition & 0 deletions src/Docfx.Common/Json/JsonUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ private static bool IsSupported()

// Intermediate types for tests. it's expected to be removed later (And return true by default).
case "Docfx.FileMapping":
case "Docfx.ListWithStringFallback":
case "Docfx.Plugins.MarkdownServiceProperties":
return true;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Docfx;
using Docfx.Common;
using FluentAssertions;

namespace docfx.Tests;

public partial class JsonSerializationTest
{
[Theory]
[TestData<ListWithStringFallback>]
public void JsonSerializationTest_ListWithStringFallback(string path)
{
// Arrange
var model = TestData.Load<ListWithStringFallback>(path);

// Act/Assert
ValidateJsonRoundTrip(model);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"string_item1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"array_item_01",
"array_item_02",
"array_item_03"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"object_item_01": "1",
"object_item_02": "2",
"object_item_03": "3"
}

0 comments on commit 657b118

Please sign in to comment.