Skip to content
Draft
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
27 changes: 27 additions & 0 deletions src/IbanNet/IIbanSpanParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#if USE_SPANS
using System.Diagnostics.CodeAnalysis;

namespace IbanNet;

/// <summary>
/// Provides parsing of international bank account numbers into an <see cref="Iban" />.
/// </summary>
internal interface IIbanSpanParser
{
/// <summary>
/// Parses the specified <paramref name="value" /> into an <see cref="Iban" />.
/// </summary>
/// <param name="value">The IBAN value to parse.</param>
/// <returns>an <see cref="Iban" /> if the <paramref name="value" /> is parsed successfully</returns>
/// <exception cref="IbanFormatException">Thrown when the specified <paramref name="value" /> is not a valid IBAN.</exception>
Iban Parse(ReadOnlySpan<char> value);

/// <summary>
/// Attempts to parse the specified <paramref name="value" /> into an <see cref="Iban" />.
/// </summary>
/// <param name="value">The IBAN value to parse.</param>
/// <param name="iban">The <see cref="Iban" /> if the <paramref name="value" /> is parsed successfully.</param>
/// <returns><see langword="true" /> if the <paramref name="value" /> is parsed successfully, or <see langword="false" /> otherwise</returns>
bool TryParse(ReadOnlySpan<char> value, [NotNullWhen(true)] out Iban? iban);
}
#endif
36 changes: 35 additions & 1 deletion src/IbanNet/Iban.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace IbanNet;
public sealed class Iban
: IEquatable<Iban>,
#if NET8_0_OR_GREATER
IParsable<Iban>,
ISpanParsable<Iban>,
#endif
IFormattable
{
Expand Down Expand Up @@ -295,6 +295,20 @@ internal static Iban Parse(string s)
return parser.Parse(s);
}

#if USE_SPANS
/// <summary>
/// Converts the specified <paramref name="s" /> into an <see cref="Iban" />.
/// </summary>
/// <param name="s">The IBAN value to parse.</param>
/// <returns>An <see cref="Iban" /> if the <paramref name="s" /> is converted successfully.</returns>
/// <exception cref="IbanFormatException">Thrown when the specified <paramref name="s" /> is not a valid IBAN.</exception>
internal static Iban Parse(ReadOnlySpan<char> s)
{
IIbanSpanParser parser = new IbanParser(IbanRegistry.Default);
return parser.Parse(s);
}
#endif

#if NET8_0_OR_GREATER
/// <summary>
/// Converts the specified <paramref name="s" /> into an <see cref="Iban" />.
Expand All @@ -306,6 +320,9 @@ internal static Iban Parse(string s)
/// <exception cref="IbanFormatException">Thrown when the specified <paramref name="s" /> is not a valid IBAN.</exception>
static Iban IParsable<Iban>.Parse(string s, IFormatProvider? provider)
=> Parse(s);

static Iban ISpanParsable<Iban>.Parse(ReadOnlySpan<char> s, IFormatProvider? provider)
=> Parse(s);
#endif

/// <summary>
Expand All @@ -320,6 +337,20 @@ internal static bool TryParse(string? s, [NotNullWhen(true)] out Iban? result)
return parser.TryParse(s, out result);
}

#if USE_SPANS
/// <summary>
/// Tries to convert the specified <paramref name="s" /> into an <see cref="Iban" />.
/// </summary>
/// <param name="s">The IBAN value to parse.</param>
/// <param name="result">The <see cref="Iban" /> if the <paramref name="s" /> is converted successfully.</param>
/// <returns><see langword="true" /> if the <paramref name="s" /> is converted successfully, or <see langword="false" /> otherwise</returns>
internal static bool TryParse(ReadOnlySpan<char> s, [NotNullWhen(true)] out Iban? result)
{
IIbanSpanParser parser = new IbanParser(IbanRegistry.Default);
return parser.TryParse(s, out result);
}
#endif

#if NET8_0_OR_GREATER
/// <summary>
/// Tries to convert the specified <paramref name="s" /> into an <see cref="Iban" />.
Expand All @@ -330,5 +361,8 @@ internal static bool TryParse(string? s, [NotNullWhen(true)] out Iban? result)
/// <returns><see langword="true" /> if the <paramref name="s" /> is converted successfully, or <see langword="false" /> otherwise</returns>
static bool IParsable<Iban>.TryParse(string? s, IFormatProvider? provider, [NotNullWhen(true)] out Iban? result)
=> TryParse(s, out result);

static bool ISpanParsable<Iban>.TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, [NotNullWhen(true)] out Iban? result)
=> TryParse(s, out result);
#endif
}
38 changes: 30 additions & 8 deletions src/IbanNet/IbanParser.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using IbanNet.Internal;
using IbanNet.Registry;

Expand All @@ -8,7 +7,11 @@ namespace IbanNet;
/// <summary>
/// Provides parsing of international bank account numbers into an <see cref="Iban" />.
/// </summary>
public sealed class IbanParser : IIbanParser
public sealed class IbanParser
: IIbanParser
#if USE_SPANS
, IIbanSpanParser
#endif
{
private readonly IIbanValidator _ibanValidator;

Expand All @@ -23,10 +26,7 @@ public IbanParser(IIbanRegistry registry)
throw new ArgumentNullException(nameof(registry));
}

_ibanValidator = new IbanValidator(new IbanValidatorOptions
{
Registry = registry
});
_ibanValidator = new IbanValidator(new IbanValidatorOptions { Registry = registry });
}

/// <summary>
Expand All @@ -39,20 +39,32 @@ public IbanParser(IIbanValidator ibanValidator)
}

/// <inheritdoc />
#if USE_SPANS
public Iban Parse(string value)
{
return value is null
? throw new ArgumentNullException(nameof(value))
: ((IIbanSpanParser)this).Parse(value);
}

Iban IIbanSpanParser.Parse(ReadOnlySpan<char> value)
{
#else
public Iban Parse(string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
#endif

if (TryParse(value, out Iban? iban, out ValidationResult validationResult, out Exception? exceptionThrown))
{
return iban;
}

string errorMessage = validationResult.Error is null || string.IsNullOrEmpty(validationResult.Error.ErrorMessage)
? string.Format(CultureInfo.CurrentCulture, Resources.IbanFormatException_The_value_0_is_not_a_valid_IBAN, value)
? Resources.IbanFormatException_The_value_is_not_a_valid_IBAN
: validationResult.Error.ErrorMessage;

if (exceptionThrown is not null)
Expand All @@ -69,14 +81,24 @@ public bool TryParse(string? value, [NotNullWhen(true)] out Iban? iban)
return TryParse(value, out iban, out _, out _);
}

private bool TryParse(

#if USE_SPANS
bool IIbanSpanParser.TryParse(ReadOnlySpan<char> value, [NotNullWhen(true)] out Iban? iban)
{
return TryParse(value, out iban, out _, out _);
}
#endif

private bool TryParse
(
#if USE_SPANS
ReadOnlySpan<char> value,
#else
string? value,
#endif
[NotNullWhen(true)] out Iban? iban,
out ValidationResult validationResult,
// ReSharper disable once RedundantNullableFlowAttribute
[MaybeNullWhen(false)] out Exception? exceptionThrown)
{
iban = null;
Expand Down
8 changes: 4 additions & 4 deletions src/IbanNet/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/IbanNet/Resources.ca.resx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="IbanFormatException_The_value_0_is_not_a_valid_IBAN" xml:space="preserve">
<value>El valor '{0}' no és un IBAN vàlid.</value>
<data name="IbanFormatException_The_value_is_not_a_valid_IBAN" xml:space="preserve">
<value>El valor no és un IBAN vàlid.</value>
</data>
<data name="ArgumentException_The_format_0_is_invalid" xml:space="preserve">
<value>El format '{0}' no és vàlid.</value>
Expand Down
4 changes: 2 additions & 2 deletions src/IbanNet/Resources.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="IbanFormatException_The_value_0_is_not_a_valid_IBAN" xml:space="preserve">
<value>Der Wert '{0}' ist keine gültige IBAN.</value>
<data name="IbanFormatException_The_value_is_not_a_valid_IBAN" xml:space="preserve">
<value>Der Wert ist keine gültige IBAN.</value>
</data>
<data name="ArgumentException_The_format_0_is_invalid" xml:space="preserve">
<value>Das Format '{0}' ist ungültig.</value>
Expand Down
4 changes: 2 additions & 2 deletions src/IbanNet/Resources.nl.resx
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="IbanFormatException_The_value_0_is_not_a_valid_IBAN" xml:space="preserve">
<value>De waarde '{0}' is geen geldige IBAN.</value>
<data name="IbanFormatException_The_value_is_not_a_valid_IBAN" xml:space="preserve">
<value>De waarde bevat geen geldige IBAN.</value>
</data>
<data name="ArgumentException_The_format_0_is_invalid" xml:space="preserve">
<value>Het formaat '{0}' is niet valide.</value>
Expand Down
4 changes: 2 additions & 2 deletions src/IbanNet/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="IbanFormatException_The_value_0_is_not_a_valid_IBAN" xml:space="preserve">
<value>The value '{0}' is not a valid IBAN.</value>
<data name="IbanFormatException_The_value_is_not_a_valid_IBAN" xml:space="preserve">
<value>The value is not a valid IBAN.</value>
</data>
<data name="ArgumentException_The_format_0_is_invalid" xml:space="preserve">
<value>The format '{0}' is invalid.</value>
Expand Down
2 changes: 1 addition & 1 deletion test/IbanNet.Tests/PublicApi/.NET_10.0.verified.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ namespace IbanNet
}
[System.ComponentModel.TypeConverter(typeof(IbanNet.TypeConverters.IbanTypeConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(IbanNet.Json.IbanJsonConverter))]
public sealed class Iban : System.IEquatable<IbanNet.Iban>, System.IFormattable, System.IParsable<IbanNet.Iban>
public sealed class Iban : System.IEquatable<IbanNet.Iban>, System.IFormattable, System.IParsable<IbanNet.Iban>, System.ISpanParsable<IbanNet.Iban>
{
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
public const int MaxLength = 34;
Expand Down
2 changes: 1 addition & 1 deletion test/IbanNet.Tests/PublicApi/.NET_8.0.verified.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ namespace IbanNet
}
[System.ComponentModel.TypeConverter(typeof(IbanNet.TypeConverters.IbanTypeConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(IbanNet.Json.IbanJsonConverter))]
public sealed class Iban : System.IEquatable<IbanNet.Iban>, System.IFormattable, System.IParsable<IbanNet.Iban>
public sealed class Iban : System.IEquatable<IbanNet.Iban>, System.IFormattable, System.IParsable<IbanNet.Iban>, System.ISpanParsable<IbanNet.Iban>
{
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
public const int MaxLength = 34;
Expand Down