parse static method

  1. @internal
PhoneNumber parse(
  1. String phoneNumber, {
  2. IsoCode? callerCountry,
  3. IsoCode? destinationCountry,
})

Implementation

@internal
static PhoneNumber parse(
  String phoneNumber, {
  IsoCode? callerCountry,
  IsoCode? destinationCountry,
}) {
  phoneNumber = TextParser.normalizePhoneNumber(phoneNumber);
  final callerMetadata = callerCountry != null
      ? MetadataFinder.findMetadataForIsoCode(callerCountry)
      : null;

  var destinationMetadata = destinationCountry != null
      ? MetadataFinder.findMetadataForIsoCode(destinationCountry)
      : null;

  final (exitCode, withoutExitCode) =
      InternationalPrefixParser.extractExitCode(
    phoneNumber,
    destinationCountryMetadata: destinationMetadata,
    callerCountryMetadata: callerMetadata,
  );

  // if no destination metadata was provided we have to find it,
  destinationMetadata ??= _findDestinationMetadata(
    exitCode: exitCode,
    phoneWithoutExitCode: withoutExitCode,
    callerMetadata: callerMetadata,
  );
  var national = withoutExitCode;
  // if there was an exit code then it is an international number followed by
  // a country code.
  // otherwise if the phone number starts with a country code, we check
  // if the phone number is valid as is and use that, other wise if it is valid
  // without the country code we remove the country code.
  final countryCode = destinationMetadata.countryCode;
  if (exitCode.isNotEmpty && national.length >= countryCode.length) {
    national = national.substring(countryCode.length);
  } else if (national.startsWith(countryCode)) {
    final withoutCountryCode = national.substring(countryCode.length);
    final (_, newNational) = NationalNumberParser.extractNationalPrefix(
      withoutCountryCode,
      destinationMetadata,
    );
    final isValid =
        Validator.validateWithPattern(destinationMetadata.isoCode, national);
    final isValidWithoutCountryCode = Validator.validateWithPattern(
      destinationMetadata.isoCode,
      newNational,
    );
    if (!isValid && isValidWithoutCountryCode) {
      national = newNational;
    }
  }

  final containsCountryCode = national.length != withoutExitCode.length;
  // normally a phone number should not contain a national prefix after the country
  // code. However we let it slide to cover a wider range of incorrect input
  var (_, nsn) = NationalNumberParser.extractNationalPrefix(
    national,
    destinationMetadata,
  );
  // if the phone number contained a country code, it should in its international form
  // and we should not transform it
  if (!containsCountryCode) {
    nsn = NationalNumberParser.transformLocalNsnToInternationalUsingPatterns(
      nsn,
      destinationMetadata,
    );
  }

  // at this point we have the phone number that has been processed, but
  // if it is invalid, we remove the processing of the nsn part
  // this allows for a better behavior in some widget input usages where the
  // text is changed on validity.
  final parsed = PhoneNumber(isoCode: destinationMetadata.isoCode, nsn: nsn);
  if (parsed.isValid()) return parsed;
  return PhoneNumber(isoCode: destinationMetadata.isoCode, nsn: national);
}