Skip to content

Commit

Permalink
Optimize query data to support JSON.
Browse files Browse the repository at this point in the history
  • Loading branch information
kingcean committed Jan 11, 2025
1 parent 4a2fcc4 commit 9c7809d
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
41 changes: 41 additions & 0 deletions Core/Collection/Dictionary/KeyValuePairs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Runtime.Serialization;
using System.Security;
using System.Text;
using System.Text.Json;
using System.Web;

using Trivial.Text;
Expand Down Expand Up @@ -142,6 +143,24 @@ public void Add(string key, long value, bool clearOthers = false)
/// <param name="value">The value.</param>
/// <param name="clearOthers">true if clear the others of the property before adding; otherwise, false.</param>
public void Add(string key, double value, bool clearOthers = false)
=> Add(key, double.IsNaN(value) ? null : value.ToString("g", CultureInfo.InvariantCulture), clearOthers);

/// <summary>
/// Adds a key and the value to the end of the key value pairs.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
/// <param name="clearOthers">true if clear the others of the property before adding; otherwise, false.</param>
public void Add(string key, float value, bool clearOthers = false)
=> Add(key, float.IsNaN(value) ? null : value.ToString("g", CultureInfo.InvariantCulture), clearOthers);

/// <summary>
/// Adds a key and the value to the end of the key value pairs.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
/// <param name="clearOthers">true if clear the others of the property before adding; otherwise, false.</param>
public void Add(string key, decimal value, bool clearOthers = false)
=> Add(key, value.ToString("g", CultureInfo.InvariantCulture), clearOthers);

/// <summary>
Expand All @@ -153,6 +172,28 @@ public void Add(string key, double value, bool clearOthers = false)
public void Add(string key, bool value, bool clearOthers = false)
=> Add(key, value ? JsonBooleanNode.TrueString : JsonBooleanNode.FalseString, clearOthers);

/// <summary>
/// Adds a key and the value to the end of the key value pairs.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
/// <param name="clearOthers">true if clear the others of the property before adding; otherwise, false.</param>
public void Add(string key, BaseJsonValueNode value, bool clearOthers = false)
{
if (value is null || value.ValueKind == JsonValueKind.Null || value.ValueKind == JsonValueKind.Undefined) Add(key, null as string, clearOthers);
else if (value.ValueKind == JsonValueKind.True) Add(key, true, clearOthers);
else if (value.ValueKind == JsonValueKind.False) Add(key, false, clearOthers);
else if (value is IJsonValueNode<string> str) Add(key, str.Value, clearOthers);
else if (value is IJsonValueNode<long> i1) Add(key, i1.Value, clearOthers);
else if (value is IJsonValueNode<double> i2) Add(key, i2.Value, clearOthers);
else if (value is IJsonValueNode<decimal> i3) Add(key, i3.Value, clearOthers);
else if (value is JsonArrayNode arr) Add(key, arr.ToString(), clearOthers);
else if (value is JsonObjectNode obj) Add(key, obj.ToString(), clearOthers);
else if (value is IJsonValueNode<bool> b) Add(key, b.Value, clearOthers);
else if (value is IJsonValueNode<int> i4) Add(key, i4.Value, clearOthers);
else if (value is IJsonValueNode<float> i5) Add(key, i5.Value, clearOthers);
}

/// <summary>
/// Adds a key and a set of value to the end of the key value pairs.
/// </summary>
Expand Down
46 changes: 46 additions & 0 deletions Core/Net/Uri/QueryData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading.Tasks;
using System.Web;

Expand All @@ -19,6 +21,7 @@ namespace Trivial.Net;
/// <summary>
/// The query data in URI after question mark.
/// </summary>
[JsonConverter(typeof(QueryDataConverter))]
[Guid("E17633F1-1C54-484C-9751-C049368AE6FD")]
public class QueryData : StringKeyValuePairs
{
Expand Down Expand Up @@ -431,3 +434,46 @@ public static async Task<QueryData> ParseAsync(Stream stream, Encoding encoding
}
#pragma warning restore IDE0056, IDE0057, CA1834
}

/// <summary>
/// The JSON converter for query data.
/// </summary>
internal class QueryDataConverter : JsonConverter<QueryData>
{
/// <inheritdoc />
public override QueryData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Null:
case JsonTokenType.False:
return null;
case JsonTokenType.True:
return new();
case JsonTokenType.String:
return QueryData.Parse(reader.GetString());
case JsonTokenType.StartObject:
{
var json = JsonObjectNode.ParseValue(ref reader);
if (json is null) return null;
var q = new QueryData();
foreach (var prop in json)
{
if (string.IsNullOrWhiteSpace(prop.Key)) continue;
q.Add(prop.Key, prop.Value);
}

return q;
}
default:
throw new JsonException($"The JSON value should be a string.");
}
}

/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, QueryData value, JsonSerializerOptions options)
{
if (value is null) writer.WriteNullValue();
else writer.WriteStringValue(value.ToString());
}
}
13 changes: 13 additions & 0 deletions Core/Text/JsonNode/Values.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,19 @@ public static void WriteTo(Stream stream, object obj, JsonSerializerOptions opti
return;
}

/// <summary>
/// Writes this instance to the specified writer as a JSON value.
/// </summary>
/// <param name="source">The object to serialize.</param>
/// <param name="writer">The writer to which to write this instance.</param>
public static void WriteTo(IJsonObjectHost source, Utf8JsonWriter writer)
{
if (writer is null) return;
var json = source?.ToJson();
if (json is null) writer.WriteNullValue();
else json.WriteTo(writer);
}

internal static void SkipComments(ref Utf8JsonReader reader)
{
while (reader.TokenType == JsonTokenType.Comment)
Expand Down

0 comments on commit 9c7809d

Please sign in to comment.