Added ability to extract pattern groups from phone number in modern way.

This commit is contained in:
23rd 2021-08-27 17:09:31 +03:00
parent e4640590d0
commit 10c8162575
2 changed files with 52 additions and 6 deletions

View file

@ -309,6 +309,9 @@ QString CountriesInstance::countryISO2ByPhone(const QString &phone) {
FormatResult CountriesInstance::format(FormatArgs args) { FormatResult CountriesInstance::format(FormatArgs args) {
// Ported from TDLib. // Ported from TDLib.
if (args.phone.isEmpty()) {
return FormatResult();
}
const auto &phoneNumber = args.phone; const auto &phoneNumber = args.phone;
const Info *bestCountryPtr = nullptr; const Info *bestCountryPtr = nullptr;
@ -343,43 +346,83 @@ FormatResult CountriesInstance::format(FormatArgs args) {
const auto formattedPart = phoneNumber.mid( const auto formattedPart = phoneNumber.mid(
bestCallingCodePtr->callingCode.size()); bestCallingCodePtr->callingCode.size());
auto formattedResult = formattedPart; auto formattedResult = formattedPart;
auto groups = QVector<int>();
auto maxMatchedDigits = size_t(0); auto maxMatchedDigits = size_t(0);
for (auto &pattern : bestCallingCodePtr->patterns) { for (auto &pattern : bestCallingCodePtr->patterns) {
auto resultGroups = QVector<int>();
auto result = QString(); auto result = QString();
auto currentPatternPos = int(0); auto currentPatternPos = int(0);
auto isFailedMatch = false; auto isFailedMatch = false;
auto matchedDigits = size_t(0); auto matchedDigits = size_t(0);
auto groupSize = 0;
for (const auto &c : formattedPart) { for (const auto &c : formattedPart) {
while ((currentPatternPos < pattern.size()) while ((currentPatternPos < pattern.size())
&& (pattern[currentPatternPos] != 'X') && (pattern[currentPatternPos] != 'X')
&& !pattern[currentPatternPos].isDigit()) { && !pattern[currentPatternPos].isDigit()) {
result += pattern[currentPatternPos++]; if (args.onlyGroups) {
resultGroups.push_back(groupSize);
groupSize = 0;
} else {
result += pattern[currentPatternPos];
}
currentPatternPos++;
} }
if (currentPatternPos == pattern.size()) { if (!args.onlyGroups && (currentPatternPos == pattern.size())) {
result += ' '; result += ' ';
} }
if ((currentPatternPos >= pattern.size()) if ((currentPatternPos >= pattern.size())
|| (pattern[currentPatternPos] == 'X')) { || (pattern[currentPatternPos] == 'X')) {
result += c;
currentPatternPos++; currentPatternPos++;
if (args.onlyGroups) {
groupSize++;
} else {
result += c;
}
} else { } else {
if (c == pattern[currentPatternPos]) { if (c == pattern[currentPatternPos]) {
matchedDigits++; matchedDigits++;
result += c;
currentPatternPos++; currentPatternPos++;
if (args.onlyGroups) {
groupSize++;
} else {
result += c;
}
} else { } else {
isFailedMatch = true; isFailedMatch = true;
break; break;
} }
} }
} }
if (groupSize) {
resultGroups.push_back(groupSize);
}
if (!isFailedMatch && matchedDigits >= maxMatchedDigits) { if (!isFailedMatch && matchedDigits >= maxMatchedDigits) {
maxMatchedDigits = matchedDigits; maxMatchedDigits = matchedDigits;
formattedResult = std::move(result); if (args.onlyGroups) {
groups = std::move(resultGroups);
} else {
formattedResult = std::move(result);
}
} }
} }
return FormatResult{ .formatted = formattedResult }; if (!args.skipCode) {
if (args.onlyGroups) {
groups.push_front(bestCallingCodePtr->callingCode.size());
} else {
formattedResult = '+'
+ bestCallingCodePtr->callingCode
+ ' '
+ std::move(formattedResult);
}
}
return FormatResult{
.formatted = (args.onlyGroups
? QString()
: std::move(formattedResult)),
.groups = std::move(groups),
};
} }
CountriesInstance &Instance() { CountriesInstance &Instance() {

View file

@ -27,10 +27,13 @@ struct Info {
struct FormatResult { struct FormatResult {
QString formatted; QString formatted;
QVector<int> groups;
}; };
struct FormatArgs { struct FormatArgs {
QString phone; QString phone;
bool onlyGroups = false;
bool skipCode = false;
}; };
class CountriesInstance final { class CountriesInstance final {