Skip to content

Commit

Permalink
closes #473
Browse files Browse the repository at this point in the history
Simplify the parse methods by using optional parameters for ParseOptions

x
  • Loading branch information
TrevorPilley committed Sep 20, 2023
1 parent 8b09bab commit 23f989a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 151 deletions.
179 changes: 48 additions & 131 deletions src/PhoneNumbers/PhoneNumber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,15 @@ protected PhoneNumber(PhoneNumberHint phoneNumberHint)
protected PhoneNumberHint Hint { get; }

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance based upon its calling code using the default <see cref="ParseOptions"/>.
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance based upon its calling code.
/// </summary>
/// <param name="value">A string containing a phone number in international format (e.g. +XX).</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value) =>
Parse(value, ParseOptions.Default);

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance based upon its calling code using the specified <see cref="ParseOptions"/>.
/// </summary>
/// <param name="value">A string containing a phone number in international format (e.g. +XX).</param>
/// <param name="options">The options for parsing the phone number.</param>
/// <exception cref="ArgumentNullException">Thrown if the specified <paramref name="options"/> is null.</exception>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value, ParseOptions options)
public static PhoneNumber Parse(string value, ParseOptions? options = null)
{
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
options = options ?? ParseOptions.Default;

foreach (var countryInfo in options.GetCountryInfos(value))
{
Expand All @@ -90,50 +77,26 @@ public static PhoneNumber Parse(string value, ParseOptions options)
}
}

throw new ParseException("Parse(value) only supports a value starting with a supported international calling code (e.g. +44), otherwise Parse(value, countryCode) must be used.");
throw new ParseException($"The value '{value}' could not be successfully parsed into a phone number for any country enabled in ParseOptions.");
}

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the specified <see cref="CountryInfo"/> using the default <see cref="ParseOptions"/>.
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the specified <see cref="CountryInfo"/>.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="value">A string containing a phone number in the international (e.g. +XX) or national format for the given <see cref="CountryInfo"/>.</param>
/// <param name="countryInfo">The <see cref="CountryInfo"/> of the country for the phone number.</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <exception cref="ArgumentNullException">Thrown if the specified <paramref name="countryInfo"/> is null.</exception>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value, CountryInfo countryInfo) =>
Parse(value, countryInfo, ParseOptions.Default);

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the given ISO 3166 Alpha-2 country code using the default <see cref="ParseOptions"/>.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="countryCode">The ISO 3166 Alpha-2 country code of the country for the phone number.</param>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value, string countryCode) =>
Parse(value, countryCode, ParseOptions.Default);

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the specified <see cref="CountryInfo"/> using the specified <see cref="ParseOptions"/>.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="countryInfo">The <see cref="CountryInfo"/> of the country for the phone number.</param>
/// <param name="options">The options for parsing the phone number.</param>
/// <exception cref="ArgumentNullException">Thrown if the specified <paramref name="countryInfo"/> or <paramref name="options"/> are null.</exception>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value, CountryInfo countryInfo, ParseOptions options)
public static PhoneNumber Parse(string value, CountryInfo countryInfo, ParseOptions? options = null)
{
if (countryInfo is null)
{
throw new ArgumentNullException(nameof(countryInfo));
}

if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
options = options ?? ParseOptions.Default;

if (!options.Countries.Contains(countryInfo))
{
Expand All @@ -147,93 +110,66 @@ public static PhoneNumber Parse(string value, CountryInfo countryInfo, ParseOpti
}

/// <summary>
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the given ISO 3166 Alpha-2 country code using the specified <see cref="ParseOptions"/>.
/// Parses the specified phone number value into a <see cref="PhoneNumber"/> instance for the given ISO 3166 Alpha-2 country code.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="value">A string containing a phone number in the international (e.g. +XX) or national format for the given ISO 3166 Alpha-2 country code.</param>
/// <param name="countryCode">The ISO 3166 Alpha-2 country code of the country for the phone number.</param>
/// <param name="options">The options for parsing the phone number.</param>
/// <exception cref="ArgumentNullException">Thrown if the specified <paramref name="options"/> is null.</exception>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <exception cref="ParseException">Thrown if the value cannot be successfully parsed into a <see cref="PhoneNumber"/>.</exception>
/// <returns>A <see cref="PhoneNumber"/> instance representing the specified phone number string value.</returns>
public static PhoneNumber Parse(string value, string countryCode, ParseOptions options)
public static PhoneNumber Parse(string value, string countryCode, ParseOptions? options = null)
{
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
options = options ?? ParseOptions.Default;

var countryInfo = options.GetCountryInfo(countryCode);

if (countryInfo is null)
{
throw new ParseException($"The country code {countryCode} is not currently supported, or is not enabled in the ParseOptions.");
throw new ParseException($"The country code {countryCode} is not currently supported, or is not enabled in ParseOptions.");
}

return Parse(value, countryInfo, options);
}

/// <summary>
/// Converts the string representation of a phone number to any <see cref="PhoneNumber"/> equivalents using the default <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="phoneNumbers">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, out IEnumerable<PhoneNumber> phoneNumbers) =>
TryParse(value, ParseOptions.Default, out phoneNumbers);

/// <summary>
/// Converts the string representation of a phone number to any possible <see cref="PhoneNumber"/> equivalents using the default <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="options">The options for parsing the phone number.</param>
/// <param name="value">A string containing a phone number in international format (e.g. +XX).</param>
/// <param name="phoneNumbers">The <see cref="PhoneNumber"/> equivalents if the conversion succeeds, otherwise null.</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, ParseOptions options, out IEnumerable<PhoneNumber> phoneNumbers)
public static bool TryParse(string value, out IEnumerable<PhoneNumber> phoneNumbers, ParseOptions? options = null)
{
if (options is not null)
{
phoneNumbers = options.Countries
.Select(x => options.ParserFactory.GetParser(x).Parse(value))
.Where(x => x.PhoneNumber is not null)
.Select(x => x.PhoneNumber)
.Cast<PhoneNumber>();
options = options ?? ParseOptions.Default;

return true;
}
phoneNumbers = options.Countries
.Select(x => options.ParserFactory.GetParser(x).Parse(value))
.Where(x => x.PhoneNumber is not null)
.Select(x => x.PhoneNumber)
.Cast<PhoneNumber>();

phoneNumbers = Enumerable.Empty<PhoneNumber>();
return false;
return phoneNumbers.Any();
}

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the default <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number in international format (e.g. +XX).</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, [NotNullWhen(true)] out PhoneNumber? phoneNumber) =>
TryParse(value, ParseOptions.Default, out phoneNumber);

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the specified <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number in international format (e.g. +XX).</param>
/// <param name="options">The options for parsing the phone number.</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, ParseOptions options, [NotNullWhen(true)] out PhoneNumber? phoneNumber)
public static bool TryParse(string value, [NotNullWhen(true)] out PhoneNumber? phoneNumber, ParseOptions? options = null)
{
if (options is not null)
options = options ?? ParseOptions.Default;

foreach (var countryInfo in options.GetCountryInfos(value))
{
foreach (var countryInfo in options.GetCountryInfos(value))
{
var result = options.ParserFactory.GetParser(countryInfo).Parse(value);
var result = options.ParserFactory.GetParser(countryInfo).Parse(value);

if (result.PhoneNumber is not null)
{
phoneNumber = result.PhoneNumber;
return true;
}
if (result.PhoneNumber is not null)
{
phoneNumber = result.PhoneNumber;
return true;
}
}

Expand All @@ -242,37 +178,18 @@ public static bool TryParse(string value, ParseOptions options, [NotNullWhen(tru
}

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the default <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="countryInfo">The <see cref="CountryInfo"/> of the country for the phone number.</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, CountryInfo countryInfo, [NotNullWhen(true)] out PhoneNumber? phoneNumber) =>
TryParse(value, countryInfo, ParseOptions.Default, out phoneNumber);

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the default <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="countryCode">The ISO 3166 Alpha-2 country code of the country for the phone number.</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, string countryCode, [NotNullWhen(true)] out PhoneNumber? phoneNumber) =>
TryParse(value, countryCode, ParseOptions.Default, out phoneNumber);

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the specified <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="value">A string containing a phone number in the international (e.g. +XX) or national format for the given <see cref="CountryInfo"/>.</param>
/// <param name="countryInfo">The <see cref="CountryInfo"/> of the country for the phone number.</param>
/// <param name="options">The options for parsing phone numbers.</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, CountryInfo countryInfo, ParseOptions options, [NotNullWhen(true)] out PhoneNumber? phoneNumber)
public static bool TryParse(string value, CountryInfo countryInfo, [NotNullWhen(true)] out PhoneNumber? phoneNumber, ParseOptions? options = null)
{
options = options ?? ParseOptions.Default;

if (countryInfo is not null &&
options is not null &&
options.Countries.Contains(countryInfo))
{
var result = options.ParserFactory.GetParser(countryInfo).Parse(value);
Expand All @@ -286,15 +203,15 @@ options is not null &&
}

/// <summary>
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent using the specified <see cref="ParseOptions"/>. A return value indicates whether the conversion succeeded.
/// Converts the string representation of a phone number to its <see cref="PhoneNumber"/> equivalent. A return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="value">A string containing a phone number.</param>
/// <param name="value">A string containing a phone number in the international (e.g. +XX) or national format for the given ISO 3166 Alpha-2 country code.</param>
/// <param name="countryCode">The ISO 3166 Alpha-2 country code of the country for the phone number.</param>
/// <param name="options">The options for parsing phone numbers.</param>
/// <param name="phoneNumber">The <see cref="PhoneNumber"/> equivalent if the conversion succeeds, otherwise null.</param>
/// <param name="options">The <see cref="ParseOptions"/> to use for parsing the phone number, if not specified (or explicitly set to null) the default parse options are used.</param>
/// <returns><c>true</c> if value was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(string value, string countryCode, ParseOptions options, [NotNullWhen(true)] out PhoneNumber? phoneNumber) =>
TryParse(value, options?.GetCountryInfo(countryCode)!, options!, out phoneNumber);
public static bool TryParse(string value, string countryCode, [NotNullWhen(true)] out PhoneNumber? phoneNumber, ParseOptions? options = null) =>
TryParse(value, (options ?? ParseOptions.Default).GetCountryInfo(countryCode)!, out phoneNumber, options);

/// <inheritdoc/>
public override string ToString() =>
Expand Down
Loading

0 comments on commit 23f989a

Please sign in to comment.