isNumberMatch method

MatchType isNumberMatch(
  1. Object firstNumberIn,
  2. Object secondNumberIn
)

Takes two phone numbers and compares them for equality.

Returns [exactMatch] if the [countryCode], NSN, presence of a leading zero for Italian numbers and any extension present are the same. Returns [nsnMatch] if either or both has no region specified, and the NSNs and extensions are the same. Returns [shortNsnMatch] if either or both has no region specified, or the region specified is the same, and one NSN could be a shorter version of the other number. This includes the case where one has an extension specified, and the other does not. Returns [noMatch] otherwise. For example, the numbers +1 345 657 1234 and 657 1234 are a [shortNsnMatch]. The numbers +1 345 657 1234 and 345 657 are a [noMatch].

{PhoneNumber|string} firstNumberIn first number to compare. If it is a string it can contain formatting, and can have country calling code specified with + at the start. {PhoneNumber|string} secondNumberIn second number to compare. If it is a string it can contain formatting, and can have country calling code specified with + at the start. returns MatchType notANumber, noMatch, shortNsnMatch, nsnMatch or exactMatch depending on the level of equality of the two numbers, described in the method definition.

Implementation

MatchType isNumberMatch(Object firstNumberIn, Object secondNumberIn) {
  // If the input arguements are strings parse them to a proto buffer format.
  // Else make copies of the phone numbers so that the numbers passed in are not
  // edited.
  PhoneNumber firstNumber;

  PhoneNumber secondNumber;
  if (firstNumberIn is String) {
    // First see if the first number has an implicit country calling code, by
    // attempting to parse it.
    try {
      firstNumber = parse(firstNumberIn, _unknownRegion);
    } on NumberParseException catch (e) {
      if (e.errorType != ErrorType.invalidCountryCode) {
        return MatchType.notANumber;
      }
      // The first number has no country calling code. exactMatch is no longer
      // possible. We parse it as if the region was the same as that for the
      // second number, and if exactMatch is returned, we replace this with
      // nsnMatch.
      if (secondNumberIn is PhoneNumber) {
        String secondNumberRegion =
            getRegionCodeForCountryCode(secondNumberIn.countryCode);
        if (secondNumberRegion != _unknownRegion) {
          try {
            firstNumber = parse(firstNumberIn, secondNumberRegion);
          } catch (e2) {
            return MatchType.notANumber;
          }

          MatchType match = isNumberMatch(firstNumber, secondNumberIn);
          if (match == MatchType.exactMatch) {
            return MatchType.nsnMatch;
          }
          return match;
        }
      }
      // If the second number is a string or doesn't have a valid country
      // calling code, we parse the first number without country calling code.
      try {
        firstNumber = _parseHelper(firstNumberIn, null, false, false);
      } catch (e2) {
        return MatchType.notANumber;
      }
    }
  } else {
    firstNumber = (firstNumberIn as PhoneNumber).deepCopy();
  }

  if (secondNumberIn is String) {
    try {
      secondNumber = parse(secondNumberIn, _unknownRegion);
      return isNumberMatch(firstNumberIn, secondNumber);
    } on NumberParseException catch (e) {
      if (e.errorType != ErrorType.invalidCountryCode) {
        return MatchType.notANumber;
      }
      return isNumberMatch(secondNumberIn, firstNumber);
    }
  } else {
    secondNumber = (secondNumberIn as PhoneNumber).deepCopy();
  }

  PhoneNumber firstNumberToCompare = _copyCoreFieldsOnly(firstNumber);
  PhoneNumber secondNumberToCompare = _copyCoreFieldsOnly(secondNumber);

  // Early exit if both had extensions and these are different.
  if (firstNumberToCompare.hasExtension_3() &&
      secondNumberToCompare.hasExtension_3() &&
      firstNumberToCompare.extension_3 != secondNumberToCompare.extension_3) {
    return MatchType.noMatch;
  }

  int firstNumberCountryCode = firstNumberToCompare.countryCode;

  int secondNumberCountryCode = secondNumberToCompare.countryCode;
  // Both had country_code specified.
  if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) {
    if (firstNumberToCompare == secondNumberToCompare) {
      return MatchType.exactMatch;
    } else if (firstNumberCountryCode == secondNumberCountryCode &&
        _isNationalNumberSuffixOfTheOther(
            firstNumberToCompare, secondNumberToCompare)) {
      // A SHORT_NSN_MATCH occurs if there is a difference because of the
      // presence or absence of an 'Italian leading zero', the presence or
      // absence of an extension, or one NSN being a shorter variant of the
      // other.
      return MatchType.shortNsnMatch;
    }
    // This is not a match.
    return MatchType.noMatch;
  }
  // Checks cases where one or both country_code fields were not specified. To
  // make equality checks easier, we first set the country_code fields to be
  // equal.
  firstNumberToCompare.countryCode = 0;
  secondNumberToCompare.countryCode = 0;
  // If all else was the same, then this is an NSN_MATCH.
  if (firstNumberToCompare == secondNumberToCompare) {
    return MatchType.nsnMatch;
  }
  if (_isNationalNumberSuffixOfTheOther(
      firstNumberToCompare, secondNumberToCompare)) {
    return MatchType.shortNsnMatch;
  }
  return MatchType.noMatch;
}