Skip to content

Commit

Permalink
add code enhancement and tests, also some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminAbt committed Apr 27, 2024
1 parent 2238eab commit bd11bbc
Show file tree
Hide file tree
Showing 37 changed files with 1,567 additions and 241 deletions.
11 changes: 10 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,13 @@ dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

# IDE0290: Use primary constructor
dotnet_diagnostic.IDE0290.severity = none
dotnet_diagnostic.IDE0290.severity = none

# MA0017: Abstract types should not have public or internal constructors
dotnet_diagnostic.MA0017.severity = none

# MA0018: Do not declare static members on generic types (deprecated; use CA1000 instead)
dotnet_diagnostic.MA0018.severity = none

# MA0154: Use langword in XML comment
dotnet_diagnostic.MA0154.severity = none
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</PropertyGroup>

<PropertyGroup Label="Project Defaults">
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup Label="Package">
Expand Down
4 changes: 4 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
</PackageVersion>
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.5.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.149">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageVersion>
</ItemGroup>

<ItemGroup Label="DevOps">
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.100"
"version": "9.0.100-preview.3"
}
}

7 changes: 7 additions & 0 deletions src/StrongOf.AspNetCore/StrongOf.AspNetCore.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup Label="Analyzers">
<PackageReference Include="Meziantou.Analyzer">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<PropertyGroup Label="Package">
<IsPackable>true</IsPackable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup Label="Analyzers">
<PackageReference Include="Meziantou.Analyzer">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<PropertyGroup Label="Package">
<IsPackable>true</IsPackable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
Expand All @@ -16,6 +23,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\StrongOf\StrongOf.csproj" />
<ProjectReference Include="..\StrongOf\StrongOf.csproj" />
</ItemGroup>
</Project>
21 changes: 13 additions & 8 deletions src/StrongOf.FluentValidation/StrongStringValidators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static class StrongStringValidators
/// <returns>The rule builder options.</returns>
public static IRuleBuilderOptions<T, TStrong?> HasMaximumLength<T, TStrong>(this IRuleBuilder<T, TStrong?> rule, int maxLength)
where TStrong : StrongString<TStrong>
=> rule.Must(content => content?.Value is null ? true : content.Value.Length <= maxLength);
=> rule.Must(content => content?.Value is null || content.Value.Length <= maxLength);

/// <summary>
/// Validates that the strong string matches a regular expression.
Expand Down Expand Up @@ -94,15 +94,20 @@ public static class StrongStringValidators
}

/// <summary>
/// Validates that the strong string only contains allowed characters.
/// Specifies that the value being validated must only contain characters from the specified collection.
/// </summary>
/// <typeparam name="T">The type of the object being validated.</typeparam>
/// <typeparam name="TStrong">The type of the strong string.</typeparam>
/// <typeparam name="T">The type of the parent object being validated.</typeparam>
/// <typeparam name="TStrong">The type of the strong string being validated.</typeparam>
/// <param name="rule">The rule builder.</param>
/// <param name="chars">The set of allowed characters.</param>
/// <param name="messagePattern">The message pattern to use if the validation fails.</param>
/// <param name="chars">The collection of allowed characters.</param>
/// <param name="messagePattern">The pattern used to format the error message if validation fails.</param>
/// <param name="formatProvider">An optional <see cref="IFormatProvider"/> that supplies culture-specific formatting information.</param>
/// <returns>The rule builder options.</returns>
public static IRuleBuilderOptionsConditions<T, TStrong?> AllowedChars<T, TStrong>(this IRuleBuilder<T, TStrong?> rule, HashSet<char> chars, string messagePattern)
/// <remarks>
/// This method adds a custom validation rule to the rule builder that checks if the value being validated contains only characters from the specified collection.
/// If the validation fails, an error message is added to the validation context using the provided message pattern.
/// </remarks>
public static IRuleBuilderOptionsConditions<T, TStrong?> AllowedChars<T, TStrong>(this IRuleBuilder<T, TStrong?> rule, ICollection<char> chars, string messagePattern, IFormatProvider? formatProvider = null)
where TStrong : StrongString<TStrong>
{
return rule.Custom((topic, context) =>
Expand All @@ -111,7 +116,7 @@ public static class StrongStringValidators
{
if (strong.ContainsInvalidChars(chars, out ICollection<char>? invalidChars))
{
context.AddFailure(string.Format(messagePattern, string.Concat(invalidChars)));
context.AddFailure(string.Format(formatProvider, messagePattern, string.Concat(invalidChars)));
}
}
});
Expand Down
5 changes: 3 additions & 2 deletions src/StrongOf.Json/StrongDateTimeOffsetJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace StrongOf.Json;
Expand Down Expand Up @@ -35,5 +36,5 @@ public class StrongDateTimeOffsetJsonConverter<TStrong> : JsonConverter<TStrong>
/// <param name="strong">The value to write.</param>
/// <param name="options">Options to control the serializer behavior during writing.</param>
public override void Write(Utf8JsonWriter writer, TStrong strong, JsonSerializerOptions options)
=> writer.WriteStringValue(strong.Value.ToString());
=> writer.WriteStringValue(strong.Value.ToString(CultureInfo.InvariantCulture));
}
5 changes: 3 additions & 2 deletions src/StrongOf.Json/StrongInt32JsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace StrongOf.Json;
Expand Down Expand Up @@ -35,5 +36,5 @@ public class StrongInt32JsonConverter<TStrong> : JsonConverter<TStrong>
/// <param name="strong">The value to write.</param>
/// <param name="options">Options to control the serializer behavior during writing.</param>
public override void Write(Utf8JsonWriter writer, TStrong strong, JsonSerializerOptions options)
=> writer.WriteStringValue(strong.Value.ToString());
=> writer.WriteStringValue(strong.Value.ToString(CultureInfo.InvariantCulture));
}
5 changes: 3 additions & 2 deletions src/StrongOf.Json/StrongInt64JsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace StrongOf.Json;
Expand Down Expand Up @@ -35,5 +36,5 @@ public class StrongInt64JsonConverter<TStrong> : JsonConverter<TStrong>
/// <param name="strong">The value to write.</param>
/// <param name="options">Options to control the serializer behavior during writing.</param>
public override void Write(Utf8JsonWriter writer, TStrong strong, JsonSerializerOptions options)
=> writer.WriteStringValue(strong.Value.ToString());
=> writer.WriteStringValue(strong.Value.ToString(CultureInfo.InvariantCulture));
}
7 changes: 7 additions & 0 deletions src/StrongOf.Json/StrongOf.Json.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup Label="Analyzers">
<PackageReference Include="Meziantou.Analyzer">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<PropertyGroup Label="Package">
<IsPackable>true</IsPackable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
Expand Down
File renamed without changes.
177 changes: 177 additions & 0 deletions src/StrongOf/StrongChar.Operators.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
namespace StrongOf;

public abstract partial class StrongChar<TStrong>
{
/// <summary>
/// Determines whether two specified instances of StrongChar are equal.
/// </summary>
/// <param name="strong">The first instance to compare.</param>
/// <param name="other">The object to compare.</param>
/// <returns>True if strong and value represent the same char; otherwise, false.</returns>
public static bool operator ==(StrongChar<TStrong>? strong, object? other)
{
if (strong is null)
{
return other is null;
}

if (other is char charValue)
{
return strong.Value == charValue;
}

if (other is StrongChar<TStrong> otherStrong)
{
return strong.Value == otherStrong.Value;
}

return false;
}

/// <summary>
/// Determines whether two specified instances of StrongChar are not equal.
/// </summary>
/// <param name="strong">The first instance to compare.</param>
/// <param name="other">The object to compare.</param>
/// <returns>True if strong and other do not represent the same char; otherwise, false.</returns>
public static bool operator !=(StrongChar<TStrong>? strong, object? other)
{
return (strong == other) is false;
}

/// <summary>
/// Determines whether a <see cref="StrongChar{TStrong}"/> object is less than another object.
/// </summary>
/// <param name="strong">The <see cref="StrongChar{TStrong}"/> object to compare.</param>
/// <param name="other">The object to compare with the <paramref name="strong"/> object.</param>
/// <returns>
/// <see langword="true"/> if the <paramref name="strong"/> object is less than the <paramref name="other"/> object;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <remarks>
/// If <paramref name="strong"/> is <see langword="null"/>, the method returns <see langword="true"/> if <paramref name="other"/> is also <see langword="null"/>, otherwise <see langword="false"/>.
/// If <paramref name="other"/> is a char, the method compares the value of <paramref name="strong"/> with the char value.
/// If <paramref name="other"/> is a <see cref="StrongChar{TStrong}"/> object, the method compares the value of <paramref name="strong"/> with the value of the other <see cref="StrongChar{TStrong}"/> object.
/// </remarks>
public static bool operator <(StrongChar<TStrong>? strong, object? other)
{
if (strong is null)
{
return other is null;
}

if (other is char charValue)
{
return strong.Value < charValue;
}

if (other is StrongChar<TStrong> otherStrong)
{
return strong.Value < otherStrong.Value;
}

return false;
}

/// <summary>
/// Determines whether a <see cref="StrongChar{TStrong}"/> object is greater than another object.
/// </summary>
/// <param name="strong">The <see cref="StrongChar{TStrong}"/> object to compare.</param>
/// <param name="other">The object to compare with the <paramref name="strong"/> object.</param>
/// <returns>
/// <see langword="true"/> if the <paramref name="strong"/> object is greater than the <paramref name="other"/> object;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <remarks>
/// If <paramref name="strong"/> is <see langword="null"/>, the method returns <see langword="true"/> if <paramref name="other"/> is also <see langword="null"/>, otherwise <see langword="false"/>.
/// If <paramref name="other"/> is a char, the method compares the value of <paramref name="strong"/> with the char value.
/// If <paramref name="other"/> is a <see cref="StrongChar{TStrong}"/> object, the method compares the value of <paramref name="strong"/> with the value of the other <see cref="StrongChar{TStrong}"/> object.
/// </remarks>
public static bool operator >(StrongChar<TStrong>? strong, object? other)
{
if (strong is null)
{
return other is null;
}

if (other is char charValue)
{
return strong.Value > charValue;
}

if (other is StrongChar<TStrong> otherStrong)
{
return strong.Value > otherStrong.Value;
}

return false;
}

/// <summary>
/// Determines whether a <see cref="StrongChar{TStrong}"/> object is less than or equal to another object.
/// </summary>
/// <param name="strong">The <see cref="StrongChar{TStrong}"/> object to compare.</param>
/// <param name="other">The object to compare with the <paramref name="strong"/> object.</param>
/// <returns>
/// <see langword="true"/> if the <paramref name="strong"/> object is less than or equal to the <paramref name="other"/> object;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <remarks>
/// If <paramref name="strong"/> is <see langword="null"/>, the method returns <see langword="true"/> if <paramref name="other"/> is also <see langword="null"/>, otherwise <see langword="false"/>.
/// If <paramref name="other"/> is a char, the method compares the value of <paramref name="strong"/> with the char value.
/// If <paramref name="other"/> is a <see cref="StrongChar{TStrong}"/> object, the method compares the value of <paramref name="strong"/> with the value of the other <see cref="StrongChar{TStrong}"/> object.
/// </remarks>
public static bool operator <=(StrongChar<TStrong>? strong, object? other)
{
if (strong is null)
{
return other is null;
}

if (other is char charValue)
{
return strong.Value <= charValue;
}

if (other is StrongChar<TStrong> otherStrong)
{
return strong.Value <= otherStrong.Value;
}

return false;
}

/// <summary>
/// Determines whether a <see cref="StrongChar{TStrong}"/> object is greater than or equal to another object.
/// </summary>
/// <param name="strong">The <see cref="StrongChar{TStrong}"/> object to compare.</param>
/// <param name="other">The object to compare with the <paramref name="strong"/> object.</param>
/// <returns>
/// <see langword="true"/> if the <paramref name="strong"/> object is greater than or equal to the <paramref name="other"/> object;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <remarks>
/// If <paramref name="strong"/> is <see langword="null"/>, the method returns <see langword="true"/> if <paramref name="other"/> is also <see langword="null"/>, otherwise <see langword="false"/>.
/// If <paramref name="other"/> is a char, the method compares the value of <paramref name="strong"/> with the char value.
/// If <paramref name="other"/> is a <see cref="StrongChar{TStrong}"/> object, the method compares the value of <paramref name="strong"/> with the value of the other <see cref="StrongChar{TStrong}"/> object.
/// </remarks>
public static bool operator >=(StrongChar<TStrong>? strong, object? other)
{
if (strong is null)
{
return other is null;
}

if (other is char charValue)
{
return strong.Value >= charValue;
}

if (other is StrongChar<TStrong> otherStrong)
{
return strong.Value >= otherStrong.Value;
}

return false;
}
}
Loading

0 comments on commit bd11bbc

Please sign in to comment.