Skip to content

Commit

Permalink
Introduction of IUnknown<TSelf> (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel committed Jan 22, 2024
1 parent 67e2d8f commit a14b4fa
Show file tree
Hide file tree
Showing 33 changed files with 283 additions and 213 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Expand Up @@ -103,6 +103,7 @@ dotnet_diagnostic.S2328.severity = none # GetHashCode() should not reference mut
dotnet_diagnostic.S2178.severity = none # Short-circuit logic should be used in boolean contexts - '&' is used instead of && to accommodate expressions with nullable booleans too.
dotnet_diagnostic.S3376.severity = none # EventArgs, and Exception type names should end with the type being extended
dotnet_diagnostic.S3376.severity = none # Attribute, EventArgs, and Exception type names should end with the type being extended
dotnet_diagnostic.S3925.severity = none # "ISerializable" should be implemented correctly
dotnet_diagnostic.S4136.severity = none # Method overloads should be grouped together

dotnet_diagnostic.S1133.severity = suggestion # Deprecated code should be removed
Expand Down Expand Up @@ -130,7 +131,6 @@ dotnet_diagnostic.S3215.severity = warning # Interface instances should not be c
dotnet_diagnostic.S3218.severity = warning # Inner class members should not shadow outer class "static" or type members
dotnet_diagnostic.S3257.severity = warning # Declarations and initializations should be as concise as possible
dotnet_diagnostic.S3776.severity = warning # Cognitive Complexity of methods should not be too high
dotnet_diagnostic.S3925.severity = warning # "ISerializable" should be implemented correctly
dotnet_diagnostic.S6354.severity = warning # Use a testable (date) time provider instead

dotnet_diagnostic.VSSpell001.severity = silent # Correct spelling
9 changes: 9 additions & 0 deletions specs/Qowaiv.Specs/Financial/Amount_specs.cs
@@ -1,5 +1,14 @@
namespace Financial.Amount_specs;

public class Has_constant
{
[Test]
public void MinValue_equal_to_decimal_MinValue() => Amount.MinValue.Should().Be(decimal.MinValue.Amount());

[Test]
public void MaxValue_equal_to_decimal_MaxValue() => Amount.MaxValue.Should().Be(decimal.MaxValue.Amount());
}

public class Min_and_max
{
[TestCase(17, 17)]
Expand Down
2 changes: 1 addition & 1 deletion src/Qowaiv/Chemistry/CasRegistryNumber.cs
Expand Up @@ -21,7 +21,7 @@ namespace Qowaiv.Chemistry;
public readonly partial struct CasRegistryNumber : IXmlSerializable, IFormattable, IEquatable<CasRegistryNumber>, IComparable, IComparable<CasRegistryNumber>
{
/// <summary>Represents an unknown (but set) CAS Registry Number.</summary>
public static readonly CasRegistryNumber Unknown = new(long.MaxValue);
public static CasRegistryNumber Unknown => new(long.MaxValue);

/// <summary>Gets the number of characters of CAS Registry Number.</summary>
public int Length => IsEmptyOrUnknown() ? 0 : (int)Math.Ceiling(Math.Log10(m_Value));
Expand Down
18 changes: 18 additions & 0 deletions src/Qowaiv/Contracts/IUnknown.cs
@@ -0,0 +1,18 @@
namespace Qowaiv;

/// <summary>
/// Defines that the default of an SVO represents the empty/not set state.
/// </summary>
/// <typeparam name="TSelf">
/// The type of the SVO.
/// </typeparam>
public interface IUnknown<TSelf> : IEmpty<TSelf> where TSelf : struct, IEmpty<TSelf>
{
#if NET8_0_OR_GREATER
/// <summary>Represents an unknown (but set) <typeparamref name="TSelf"/>.</summary>
static abstract TSelf Unknown { get; }
#endif

/// <summary>False if <typeparamref name="TSelf"/> is empty or unknown, otherwise true.</summary>
bool IsKnown { get; }
}
6 changes: 3 additions & 3 deletions src/Qowaiv/Customization/Svo.cs
@@ -1,4 +1,4 @@
#pragma warning disable S1210
#pragma warning disable S1210
// "Equals" and the comparison operators should be overridden when implementing "IComparable"
// See README.md => Sortable
using Qowaiv.Conversion.Customization;
Expand All @@ -17,7 +17,7 @@ namespace Qowaiv.Customization;
#if NET6_0_OR_GREATER
[System.Text.Json.Serialization.JsonConverter(typeof(Json.Customization.GenericSvoJsonConverter))]
#endif
public readonly struct Svo<TSvoBehavior> : IXmlSerializable, IFormattable, IEquatable<Svo<TSvoBehavior>>, IComparable, IComparable<Svo<TSvoBehavior>>, IEmpty<Svo<TSvoBehavior>>
public readonly struct Svo<TSvoBehavior> : IXmlSerializable, IFormattable, IEquatable<Svo<TSvoBehavior>>, IComparable, IComparable<Svo<TSvoBehavior>>, IUnknown<Svo<TSvoBehavior>>
#if NET8_0_OR_GREATER
, IEqualityOperators<Svo<TSvoBehavior>, Svo<TSvoBehavior>, bool>
, IParsable<Svo<TSvoBehavior>>
Expand All @@ -34,7 +34,7 @@ namespace Qowaiv.Customization;
public static Svo<TSvoBehavior> Empty => default;

/// <summary>Represents an unknown (but set) Single Value Object.</summary>
public static readonly Svo<TSvoBehavior> Unknown = new(SvoBehavior.unknown);
public static Svo<TSvoBehavior> Unknown => new(SvoBehavior.unknown);

/// <summary>Initializes a new instance of the <see cref="Svo{TSvoBehavior}"/> struct.</summary>
private Svo(string? value) => m_Value = value;
Expand Down
2 changes: 1 addition & 1 deletion src/Qowaiv/EmailAddress.cs
Expand Up @@ -23,7 +23,7 @@ namespace Qowaiv;
public const int MaxLength = 254;

/// <summary>Represents an unknown (but set) email address.</summary>
public static readonly EmailAddress Unknown = new("?");
public static EmailAddress Unknown => new("?");

/// <summary>Gets the number of characters of email address.</summary>
public int Length => m_Value is { Length: > 1 } ? m_Value.Length : 0;
Expand Down
2 changes: 1 addition & 1 deletion src/Qowaiv/Financial/BusinessIdentifierCode.cs
Expand Up @@ -43,7 +43,7 @@ namespace Qowaiv.Financial;
#endif

/// <summary>Represents an unknown (but set) BIC.</summary>
public static readonly BusinessIdentifierCode Unknown = new("ZZZZZZZZZZZ");
public static BusinessIdentifierCode Unknown => new("ZZZZZZZZZZZ");

/// <summary>Gets the number of characters of BIC.</summary>
public int Length => IsUnknown() ? 0 : m_Value?.Length ?? 0;
Expand Down
2 changes: 1 addition & 1 deletion src/Qowaiv/Financial/Currency.cs
Expand Up @@ -29,7 +29,7 @@ namespace Qowaiv.Financial;
public readonly partial struct Currency : IXmlSerializable, IFormattable, IFormatProvider, IEquatable<Currency>, IComparable, IComparable<Currency>
{
/// <summary>Represents an unknown (but set) currency.</summary>
public static readonly Currency Unknown = new("ZZZ");
public static Currency Unknown => new("ZZZ");

/// <summary>Gets a currency based on the current thread.</summary>
public static Currency Current => Thread.CurrentThread.GetValue<Currency>();
Expand Down
2 changes: 1 addition & 1 deletion src/Qowaiv/Financial/InternationalBankAccountNumber.cs
Expand Up @@ -27,7 +27,7 @@ namespace Qowaiv.Financial;
public readonly partial struct InternationalBankAccountNumber : IXmlSerializable, IFormattable, IEquatable<InternationalBankAccountNumber>, IComparable, IComparable<InternationalBankAccountNumber>
{
/// <summary>Represents an unknown (but set) IBAN.</summary>
public static readonly InternationalBankAccountNumber Unknown = new("ZZ");
public static InternationalBankAccountNumber Unknown => new("ZZ");

/// <summary>Gets the number of characters of IBAN.</summary>
public int Length => m_Value is { Length: > 2 } ? m_Value.Length : 0;
Expand Down
27 changes: 15 additions & 12 deletions src/Qowaiv/Generated/Chemistry/CasRegistryNumber.generated.cs
Expand Up @@ -18,18 +18,6 @@ public partial struct CasRegistryNumber
/// <summary>The inner value of the CAS Registry Number.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly long m_Value;

/// <summary>False if the CAS Registry Number is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the CAS Registry Number is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the CAS Registry Number is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct CasRegistryNumber : IEmpty<CasRegistryNumber>
Expand All @@ -46,6 +34,21 @@ public partial struct CasRegistryNumber : IEmpty<CasRegistryNumber>
public bool IsEmpty() => !HasValue;
}

public partial struct CasRegistryNumber : IUnknown<CasRegistryNumber>
{
/// <summary>False if the CAS Registry Number is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the CAS Registry Number is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the CAS Registry Number is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct CasRegistryNumber : IEquatable<CasRegistryNumber>
#if NET8_0_OR_GREATER
, IEqualityOperators<CasRegistryNumber, CasRegistryNumber, bool>
Expand Down
27 changes: 15 additions & 12 deletions src/Qowaiv/Generated/EmailAddress.generated.cs
Expand Up @@ -18,18 +18,6 @@ public partial struct EmailAddress
/// <summary>The inner value of the email address.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? m_Value;

/// <summary>False if the email address is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the email address is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the email address is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct EmailAddress : IEmpty<EmailAddress>
Expand All @@ -46,6 +34,21 @@ public partial struct EmailAddress : IEmpty<EmailAddress>
public bool IsEmpty() => !HasValue;
}

public partial struct EmailAddress : IUnknown<EmailAddress>
{
/// <summary>False if the email address is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the email address is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the email address is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct EmailAddress : IEquatable<EmailAddress>
#if NET8_0_OR_GREATER
, IEqualityOperators<EmailAddress, EmailAddress, bool>
Expand Down
27 changes: 15 additions & 12 deletions src/Qowaiv/Generated/Financial/BusinessIdentifierCode.generated.cs
Expand Up @@ -18,18 +18,6 @@ public partial struct BusinessIdentifierCode
/// <summary>The inner value of the BIC.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? m_Value;

/// <summary>False if the BIC is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the BIC is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the BIC is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct BusinessIdentifierCode : IEmpty<BusinessIdentifierCode>
Expand All @@ -46,6 +34,21 @@ public partial struct BusinessIdentifierCode : IEmpty<BusinessIdentifierCode>
public bool IsEmpty() => !HasValue;
}

public partial struct BusinessIdentifierCode : IUnknown<BusinessIdentifierCode>
{
/// <summary>False if the BIC is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the BIC is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the BIC is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct BusinessIdentifierCode : IEquatable<BusinessIdentifierCode>
#if NET8_0_OR_GREATER
, IEqualityOperators<BusinessIdentifierCode, BusinessIdentifierCode, bool>
Expand Down
27 changes: 15 additions & 12 deletions src/Qowaiv/Generated/Financial/Currency.generated.cs
Expand Up @@ -18,18 +18,6 @@ public partial struct Currency
/// <summary>The inner value of the currency.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? m_Value;

/// <summary>False if the currency is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the currency is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the currency is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct Currency : IEmpty<Currency>
Expand All @@ -46,6 +34,21 @@ public partial struct Currency : IEmpty<Currency>
public bool IsEmpty() => !HasValue;
}

public partial struct Currency : IUnknown<Currency>
{
/// <summary>False if the currency is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the currency is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the currency is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct Currency : IEquatable<Currency>
#if NET8_0_OR_GREATER
, IEqualityOperators<Currency, Currency, bool>
Expand Down
Expand Up @@ -18,18 +18,6 @@ public partial struct InternationalBankAccountNumber
/// <summary>The inner value of the IBAN.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? m_Value;

/// <summary>False if the IBAN is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the IBAN is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the IBAN is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct InternationalBankAccountNumber : IEmpty<InternationalBankAccountNumber>
Expand All @@ -46,6 +34,21 @@ public partial struct InternationalBankAccountNumber : IEmpty<InternationalBankA
public bool IsEmpty() => !HasValue;
}

public partial struct InternationalBankAccountNumber : IUnknown<InternationalBankAccountNumber>
{
/// <summary>False if the IBAN is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the IBAN is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the IBAN is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct InternationalBankAccountNumber : IEquatable<InternationalBankAccountNumber>
#if NET8_0_OR_GREATER
, IEqualityOperators<InternationalBankAccountNumber, InternationalBankAccountNumber, bool>
Expand Down
27 changes: 15 additions & 12 deletions src/Qowaiv/Generated/Globalization/Country.generated.cs
Expand Up @@ -18,18 +18,6 @@ public partial struct Country
/// <summary>The inner value of the country.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? m_Value;

/// <summary>False if the country is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the country is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the country is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct Country : IEmpty<Country>
Expand All @@ -46,6 +34,21 @@ public partial struct Country : IEmpty<Country>
public bool IsEmpty() => !HasValue;
}

public partial struct Country : IUnknown<Country>
{
/// <summary>False if the country is empty or unknown, otherwise true.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public bool IsKnown => m_Value != default && m_Value != Unknown.m_Value;

/// <summary>Returns true if the country is unknown, otherwise false.</summary>
[Pure]
public bool IsUnknown() => m_Value == Unknown.m_Value;

/// <summary>Returns true if the country is empty or unknown, otherwise false.</summary>
[Pure]
public bool IsEmptyOrUnknown() => IsEmpty() || IsUnknown();
}

public partial struct Country : IEquatable<Country>
#if NET8_0_OR_GREATER
, IEqualityOperators<Country, Country, bool>
Expand Down

0 comments on commit a14b4fa

Please sign in to comment.