parse static method
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);
}