Skip to content

Added culture support via IParseable and ToString #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/dotnet-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run: dotnet pack -v normal -c Release --no-restore --include-symbols --include-source -p:SymbolPackageFormat=snupkg -p:PackageVersion=1.0.0-pre+$GITHUB_RUN_ID src/$PROJECT_NAME/$PROJECT_NAME.*proj
- name: Upload Artifact
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: nupkg
path: ./artifacts/pkg/Release/${{ env.PROJECT_NAME }}.*.nupkg
Expand All @@ -55,7 +55,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4
with:
name: nupkg
- name: Push to GitHub Feed
Expand Down
23 changes: 22 additions & 1 deletion src/Synercoding.Primitives/JsonConverters/PointJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Point"/> object to or from JSON.
/// </summary>
public class PointJsonConverter : JsonConverter<Point>
{
/// <summary>
/// Thread-safe instance of <see cref="PointJsonConverter"/> to be reused.
/// </summary>
public static PointJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Point"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Point"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Point"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Point"/>.</exception>
public override Point Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
Expand Down Expand Up @@ -50,8 +65,14 @@ public override Point Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe
throw new JsonException();
}

/// <summary>
/// Write a <see cref="Point"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Point"/> to.</param>
/// <param name="value">The <see cref="Point"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Point value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Rectangle"/> object to or from JSON.
/// </summary>
public class RectangleJsonConverter : JsonConverter<Rectangle>
{
/// <summary>
/// Thread-safe instance of <see cref="RectangleJsonConverter"/> to be reused.
/// </summary>
public static RectangleJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Rectangle"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Rectangle"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Rectangle"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Rectangle"/>.</exception>
public override Rectangle Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
Expand Down Expand Up @@ -58,8 +73,14 @@ public override Rectangle Read(ref Utf8JsonReader reader, Type typeToConvert, Js
throw new JsonException();
}

/// <summary>
/// Write a <see cref="Rectangle"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Rectangle"/> to.</param>
/// <param name="value">The <see cref="Rectangle"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Rectangle value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}
23 changes: 22 additions & 1 deletion src/Synercoding.Primitives/JsonConverters/SizeJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Size"/> object to or from JSON.
/// </summary>
public class SizeJsonConverter : JsonConverter<Size>
{
/// <summary>
/// Thread-safe instance of <see cref="SizeJsonConverter"/> to be reused.
/// </summary>
public static SizeJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Size"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Value"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Size"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Size"/>.</exception>
public override Size Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
Expand Down Expand Up @@ -50,8 +65,14 @@ public override Size Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSer
throw new JsonException();
}

/// <summary>
/// Write a <see cref="Size"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Size"/> to.</param>
/// <param name="value">The <see cref="Size"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Size value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Spacing"/> object to or from JSON.
/// </summary>
public class SpacingJsonConverter : JsonConverter<Spacing>
{
/// <summary>
/// Thread-safe instance of <see cref="SpacingJsonConverter"/> to be reused.
/// </summary>
public static SpacingJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Spacing"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Spacing"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Spacing"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Spacing"/>.</exception>
public override Spacing Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
Expand Down Expand Up @@ -58,8 +73,14 @@ public override Spacing Read(ref Utf8JsonReader reader, Type typeToConvert, Json
throw new JsonException();
}

/// <summary>
/// Write a <see cref="Spacing"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Spacing"/> to.</param>
/// <param name="value">The <see cref="Spacing"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Spacing value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}
25 changes: 23 additions & 2 deletions src/Synercoding.Primitives/JsonConverters/UnitJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,50 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Unit"/> object to or from JSON.
/// </summary>
public class UnitJsonConverter : JsonConverter<Unit>
{
/// <summary>
/// Thread-safe instance of <see cref="UnitJsonConverter"/> to be reused.
/// </summary>
public static UnitJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Unit"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Unit"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Unit"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Unit"/>.</exception>
public override Unit Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
throw new JsonException();

var textValue = reader.GetString() ?? throw new JsonException();

if (Unit.TryParse(textValue, out var unit))
if (Unit.TryParse(textValue, CultureInfo.InvariantCulture, out var unit))
return unit;

throw new JsonException();
}

/// <summary>
/// Write a <see cref="Unit"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Unit"/> to.</param>
/// <param name="value">The <see cref="Unit"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Unit value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}

25 changes: 23 additions & 2 deletions src/Synercoding.Primitives/JsonConverters/ValueJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Synercoding.Primitives.JsonConverters;

/// <summary>
/// Converts a <see cref="Value"/> object to or from JSON.
/// </summary>
public class ValueJsonConverter : JsonConverter<Value>
{
/// <summary>
/// Thread-safe instance of <see cref="ValueJsonConverter"/> to be reused.
/// </summary>
public static ValueJsonConverter Instance { get; } = new();

/// <summary>
/// Read a <see cref="Value"/> object from the <paramref name="reader"/>.
/// </summary>
/// <param name="reader">The reader that should contain a <see cref="Value"/>.</param>
/// <param name="typeToConvert">The expected type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The <see cref="Value"/> that was read from the <paramref name="reader"/>.</returns>
/// <exception cref="JsonException">Throws when the <paramref name="reader"/> does not contain <see cref="Value"/>.</exception>
public override Value Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var textValue = reader.GetString() ?? throw new JsonException();

if (Value.TryParse(textValue, out var value))
if (Value.TryParse(textValue, CultureInfo.InvariantCulture, out var value))
return value;

throw new JsonException();
Expand Down Expand Up @@ -50,8 +65,14 @@ public override Value Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe
throw new JsonException();
}

/// <summary>
/// Write a <see cref="Value"/> to the <paramref name="writer"/>.
/// </summary>
/// <param name="writer">Writer to write the <see cref="Value"/> to.</param>
/// <param name="value">The <see cref="Value"/> to write.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, Value value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
}
2 changes: 1 addition & 1 deletion src/Synercoding.Primitives/PackageDetails.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Product>Synercoding.Primitives</Product>
<Title>Synercoding.Primitives</Title>
<Description>Primitives with units attached (think mm, cm, in, px) that can be used for 2D graphics.</Description>
<PackageReleaseNotes>Limit to latest .NET version (8) and add System.Json serialization support.</PackageReleaseNotes>
<PackageReleaseNotes>Added IParsable support and added overload for ToString to be culture aware.</PackageReleaseNotes>
</PropertyGroup>

</Project>
Loading