Reorganize imports and exports

This commit is contained in:
Vlasislav Kashin
2025-07-13 21:16:14 +03:00
parent 71d2562d83
commit 7f7bab7f16
13 changed files with 769 additions and 71 deletions

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::phonemetadata::PhoneNumberDesc;
use crate::PhoneNumberDesc;
/// Internal phonenumber matching API used to isolate the underlying
/// implementation of the matcher and allow different implementations to be

View File

@@ -41,9 +41,24 @@ pub use phonenumberutil::{
ExtractNumberResult,
PhoneNumberUtil
},
errors,
enums,
errors::{
ExtractNumberError,
GetExampleNumberError,
ParseError,
NotANumberError,
ValidationError,
InternalLogicError,
InvalidNumberError,
InvalidMetadataForValidRegionError
},
enums::{
MatchType,
PhoneNumberType,
NumberLengthType,
PhoneNumberFormat
},
};
pub use generated::proto::phonemetadata;
pub use generated::proto::phonenumber;
pub use generated::proto::phonemetadata::{*};
pub use generated::proto::phonenumber::PhoneNumber;
pub use generated::proto::phonenumber::phone_number::CountryCodeSource;
mod tests;

View File

@@ -20,8 +20,8 @@ use strum::IntoEnumIterator;
use crate::{
interfaces::MatcherApi, generated::metadata::METADATA,
phonemetadata::{PhoneMetadata, PhoneMetadataCollection, PhoneNumberDesc},
phonenumber::PhoneNumber,
PhoneMetadata, PhoneMetadataCollection, PhoneNumberDesc,
PhoneNumber,
};

View File

@@ -16,7 +16,7 @@
use std::borrow::Cow;
use crate::phonenumber::phone_number::CountryCodeSource;
use crate::CountryCodeSource;
#[derive(Debug)]
pub struct PhoneNumberWithCountryCodeSource<'a> {

View File

@@ -26,6 +26,7 @@ use std::sync::LazyLock;
pub use enums::{MatchType, PhoneNumberFormat, PhoneNumberType, NumberLengthType};
use crate::phonenumberutil::phonenumberutil::PhoneNumberUtil;
/// Singleton instance of phone number util for general use
pub static PHONE_NUMBER_UTIL: LazyLock<PhoneNumberUtil> = LazyLock::new(|| {
PhoneNumberUtil::new()
});

View File

@@ -21,11 +21,11 @@ use std::{
use super::phone_number_regexps_and_mappings::PhoneNumberRegExpsAndMappings;
use crate::{
errors::NotANumberError, region_code::RegionCode, interfaces::MatcherApi, macros::owned_from_cow_or, phonemetadata::PhoneMetadataCollection, phonenumberutil::{
region_code::RegionCode, interfaces::MatcherApi, macros::owned_from_cow_or, PhoneMetadataCollection, phonenumberutil::{
errors::{
ExtractNumberError, GetExampleNumberError, InternalLogicError,
InvalidMetadataForValidRegionError, InvalidNumberError, ParseError,
ValidationError,
ValidationError, NotANumberError
}, helper_constants::{
DEFAULT_EXTN_PREFIX, MAX_LENGTH_COUNTRY_CODE, MAX_LENGTH_FOR_NSN, MIN_LENGTH_FOR_NSN,
NANPA_COUNTRY_CODE, PLUS_SIGN, REGION_CODE_FOR_NON_GEO_ENTITY, RFC3966_EXTN_PREFIX,
@@ -37,8 +37,8 @@ use crate::{
test_number_length_with_unknown_type,
}, helper_types::{PhoneNumberWithCountryCodeSource}, MatchType, PhoneNumberFormat, PhoneNumberType, NumberLengthType
},
phonemetadata::{NumberFormat, PhoneMetadata, PhoneNumberDesc},
phonenumber::{phone_number::CountryCodeSource, PhoneNumber},
NumberFormat, PhoneMetadata, PhoneNumberDesc,
CountryCodeSource, PhoneNumber,
regex_based_matcher::RegexBasedMatcher, regex_util::{RegexConsume, RegexFullMatch}, regexp_cache::ErrorInvalidRegex, string_util::strip_cow_prefix
};
@@ -189,10 +189,11 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `region_code` - The region code for which to get the types.
pub fn get_supported_types_for_region(
pub fn get_supported_types_for_region<S: AsRef<str>>(
&self,
region_code: &str,
region_code: S,
) -> Option<HashSet<PhoneNumberType>> {
let region_code = region_code.as_ref();
self.region_to_metadata_map
.get(region_code)
.and_then(|metadata| Some(get_supported_types_for_metadata(metadata)))
@@ -227,12 +228,12 @@ impl PhoneNumberUtil {
return &self.reg_exps.extn_patterns_for_matching;
}
pub fn starts_with_plus_chars_pattern(&self, phone_number: &str) -> bool {
self.reg_exps.plus_chars_pattern.matches_start(phone_number)
pub fn starts_with_plus_chars_pattern<S: AsRef<str>>(&self, phone_number: S) -> bool {
self.reg_exps.plus_chars_pattern.matches_start(phone_number.as_ref())
}
pub fn contains_only_valid_digits(&self, s: &str) -> bool {
self.reg_exps.digits_pattern.full_match(s)
pub fn contains_only_valid_digits<S: AsRef<str>>(&self, s: S) -> bool {
self.reg_exps.digits_pattern.full_match(s.as_ref())
}
pub(crate) fn trim_unwanted_end_chars<'a>(&self, phone_number: &'a str) -> &'a str {
@@ -704,11 +705,12 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to format.
/// * `carrier_code` - The carrier code to include in the formatted number.
pub fn format_national_number_with_carrier_code(
pub fn format_national_number_with_carrier_code<S: AsRef<str>>(
&self,
phone_number: &PhoneNumber,
carrier_code: &str,
carrier_code: S,
) -> RegexResult<String> {
let carrier_code= carrier_code.as_ref();
let country_calling_code = phone_number.country_code();
let national_significant_number = self.get_national_significant_number(phone_number);
let region_code = self.get_region_code_for_country_code(country_calling_code);
@@ -752,15 +754,15 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to format.
/// * `fallback_carrier_code` - The carrier code to use if a preferred one is not available.
pub fn format_national_number_with_preferred_carrier_code(
pub fn format_national_number_with_preferred_carrier_code<S: AsRef<str>>(
&self,
phone_number: &PhoneNumber,
fallback_carrier_code: &str,
fallback_carrier_code: S,
) -> RegexResult<String> {
let carrier_code = if !phone_number.preferred_domestic_carrier_code().is_empty() {
phone_number.preferred_domestic_carrier_code()
} else {
fallback_carrier_code
fallback_carrier_code.as_ref()
};
self.format_national_number_with_carrier_code(phone_number, carrier_code)
}
@@ -782,12 +784,13 @@ impl PhoneNumberUtil {
/// * `phone_number` - The phone number to format.
/// * `calling_from` - The region where the call is being placed.
/// * `with_formatting` - Whether to include formatting characters.
pub fn format_number_for_mobile_dialing<'b>(
pub fn format_number_for_mobile_dialing<'b, S: AsRef<str>>(
&self,
phone_number: &'b PhoneNumber,
calling_from: &str,
calling_from: S,
with_formatting: bool,
) -> InternalLogicResult<Cow<'b, str>> {
let calling_from = calling_from.as_ref();
let country_calling_code = phone_number.country_code();
if !self.has_valid_country_calling_code(country_calling_code) {
return if phone_number.has_raw_input() {
@@ -1120,8 +1123,8 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `phone_number` - The phone number string to normalize.
pub fn normalize_digits_only<'a>(&self, phone_number: &'a str) -> String {
dec_from_char::normalize_decimals_filtering(phone_number)
pub fn normalize_digits_only<S: AsRef<str>>(&self, phone_number: S) -> String {
dec_from_char::normalize_decimals_filtering(phone_number.as_ref())
}
/// Formats a phone number for calling from outside the number's region.
@@ -1130,11 +1133,12 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to format.
/// * `calling_from` - The region where the call is being placed from.
pub fn format_out_of_country_calling_number<'a>(
pub fn format_out_of_country_calling_number<'a, S: AsRef<str>>(
&self,
phone_number: &'a PhoneNumber,
calling_from: &str,
calling_from: S,
) -> InternalLogicResult<Cow<'a, str>> {
let calling_from = calling_from.as_ref();
let Some(metadata_calling_from) = self.region_to_metadata_map.get(calling_from) else {
trace!(
"Trying to format number from invalid region {calling_from}\
@@ -1253,11 +1257,12 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to format.
/// * `region_calling_from` - The region from which the number was originally parsed.
pub fn format_in_original_format<'a>(
pub fn format_in_original_format<'a, S: AsRef<str>>(
&self,
phone_number: &'a PhoneNumber,
region_calling_from: &str,
region_calling_from: S,
) -> InternalLogicResult<Cow<'a, str>> {
let region_calling_from = region_calling_from.as_ref();
if phone_number.has_raw_input() && !self.has_formatting_pattern_for_number(phone_number)? {
// We check if we have the formatting pattern because without that, we might
// format the number as a group without national prefix.
@@ -1404,8 +1409,10 @@ impl PhoneNumberUtil {
///
/// * `number_to_parse` - The number string to parse.
/// * `default_region` - The region to assume if the number is not in international format.
pub fn parse(&self, number_to_parse: &str, default_region: &str) -> ParseResult<PhoneNumber> {
self.parse_helper(number_to_parse, default_region, false, true)
pub fn parse<S1: AsRef<str>, S2: AsRef<str>>(
&self, number_to_parse: S1, default_region: S2
) -> ParseResult<PhoneNumber> {
self.parse_helper(number_to_parse.as_ref(), default_region.as_ref(), false, true)
}
/// Parses a string into a phone number object, keeping the raw input.
@@ -1414,12 +1421,12 @@ impl PhoneNumberUtil {
///
/// * `number_to_parse` - The number string to parse.
/// * `default_region` - The region to assume if the number is not in international format.
pub fn parse_and_keep_raw_input(
pub fn parse_and_keep_raw_input<S1: AsRef<str>, S2: AsRef<str>>(
&self,
number_to_parse: &str,
default_region: &str,
number_to_parse: S1,
default_region: S2,
) -> ParseResult<PhoneNumber> {
self.parse_helper(number_to_parse, default_region, true, true)
self.parse_helper(number_to_parse.as_ref(), default_region.as_ref(), true, true)
}
/// Checks if a phone number is valid.
@@ -1438,11 +1445,12 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to validate.
/// * `region_code` - The region to validate against.
pub fn is_valid_number_for_region(
pub fn is_valid_number_for_region<S: AsRef<str>>(
&self,
phone_number: &PhoneNumber,
region_code: &str,
region_code: S,
) -> bool {
let region_code = region_code.as_ref();
let country_code = phone_number.country_code();
let metadata = self.get_metadata_for_region_or_calling_code(country_code, region_code);
if let Some(metadata) = metadata.filter(|metadata| {
@@ -1465,11 +1473,12 @@ impl PhoneNumberUtil {
///
/// * `phone_number` - The phone number to format.
/// * `calling_from` - The region where the call is being placed from.
pub fn format_out_of_country_keeping_alpha_chars<'a>(
pub fn format_out_of_country_keeping_alpha_chars<'a, S: AsRef<str>>(
&self,
phone_number: &'a PhoneNumber,
calling_from: &str,
calling_from: S,
) -> InternalLogicResult<Cow<'a, str>> {
let calling_from = calling_from.as_ref();
// If there is no raw input, then we can't keep alpha characters because there
// aren't any. In this case, we return FormatOutOfCountryCallingNumber.
if phone_number.raw_input().is_empty() {
@@ -1797,11 +1806,13 @@ impl PhoneNumberUtil {
///
/// * `number` - The number string to check.
/// * `region_code` - The region to check against.
pub fn is_possible_number_for_string(
pub fn is_possible_number_for_string<S1: AsRef<str>, S2: AsRef<str>>(
&self,
phone_number: &str,
region_dialing_from: &str,
phone_number: S1,
region_dialing_from: S2,
) -> bool {
let phone_number = phone_number.as_ref();
let region_dialing_from = region_dialing_from.as_ref();
match self.parse(phone_number, region_dialing_from) {
Ok(number_proto) => self.is_possible_number(&number_proto),
@@ -2037,7 +2048,8 @@ impl PhoneNumberUtil {
/// method does not require the number to be normalized in advance - but does
/// assume that leading non-number symbols have been removed, such as by the
/// method `ExtractPossibleNumber`.
pub fn is_viable_phone_number(&self, phone_number: &str) -> bool {
pub fn is_viable_phone_number<S: AsRef<str>>(&self, phone_number: S) -> bool {
let phone_number = phone_number.as_ref();
if phone_number.len() < MIN_LENGTH_FOR_NSN {
false
} else {
@@ -2216,8 +2228,8 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `region_code` - The region for which to get an example number.
pub fn get_example_number(&self, region_code: &str) -> ExampleNumberResult {
self.get_example_number_for_type_and_region_code(region_code, PhoneNumberType::FixedLine)
pub fn get_example_number<S: AsRef<str>>(&self, region_code: S) -> ExampleNumberResult {
self.get_example_number_for_type_and_region_code(region_code.as_ref(), PhoneNumberType::FixedLine)
}
/// Gets an example of an invalid phone number for a given region.
@@ -2225,7 +2237,8 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `region_code` - The region for which to get an invalid example number.
pub fn get_invalid_example_number(&self, region_code: &str) -> ExampleNumberResult {
pub fn get_invalid_example_number<S: AsRef<str>>(&self, region_code: S) -> ExampleNumberResult {
let region_code = region_code.as_ref();
let Some(region_metadata) = self.region_to_metadata_map.get(region_code) else {
warn!("Invalid or unknown region code ({}) provided.", region_code);
return Err(GetExampleNumberError::InvalidMetadata);
@@ -2281,11 +2294,12 @@ impl PhoneNumberUtil {
///
/// * `region_code` - The region for which to get an example number.
/// * `number_type` - The type of number to get an example for.
pub fn get_example_number_for_type_and_region_code(
pub fn get_example_number_for_type_and_region_code<S: AsRef<str>>(
&self,
region_code: &str,
region_code: S,
phone_number_type: PhoneNumberType,
) -> ExampleNumberResult {
let region_code = region_code.as_ref();
let Some(region_metadata) = self.region_to_metadata_map.get(region_code) else {
warn!("Invalid or unknown region code ({}) provided.", region_code);
return Err(GetExampleNumberError::InvalidMetadata);
@@ -2471,7 +2485,8 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `phone_number` - Number to normalize.
pub fn normalize(&self, phone_number: &str) -> String {
pub fn normalize<S: AsRef<str>>(&self, phone_number: S) -> String {
let phone_number = phone_number.as_ref();
if self
.reg_exps
.valid_alpha_phone_pattern
@@ -2788,8 +2803,10 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `phone_number` - The phone number string with alpha characters.
pub fn convert_alpha_characters_in_number(&self, phone_number: &str) -> String {
normalize_helper(&self.reg_exps.alpha_phone_mappings, false, phone_number)
pub fn convert_alpha_characters_in_number<S: AsRef<str>>(&self, phone_number: S) -> String {
normalize_helper(
&self.reg_exps.alpha_phone_mappings, false, phone_number.as_ref()
)
}
/// Checks whether two phone numbers match.
@@ -2856,11 +2873,13 @@ impl PhoneNumberUtil {
///
/// * `number1` - The first phone number to compare.
/// * `number2` - The second phone number to compare.
pub fn is_number_match_with_two_strings(
pub fn is_number_match_with_two_strings<S1: AsRef<str>, S2: AsRef<str>>(
&self,
first_number: &str,
second_number: &str,
first_number: S1,
second_number: S2,
) -> MatchResult {
let first_number = first_number.as_ref();
let second_number = second_number.as_ref();
match self.parse(first_number, RegionCode::get_unknown()) {
Ok(first_number_as_proto) => {
return self.is_number_match_with_one_string(&first_number_as_proto, second_number);
@@ -2899,11 +2918,13 @@ impl PhoneNumberUtil {
///
/// * `number1` - The first phone number to compare.
/// * `number2` - The second phone number to compare.
pub fn is_number_match_with_one_string(
pub fn is_number_match_with_one_string<S: AsRef<str>>(
&self,
first_number: &PhoneNumber,
second_number: &str,
second_number: S,
) -> MatchResult {
let second_number = second_number.as_ref();
// First see if the second number has an implicit country calling code, by
// attempting to parse it.
match self.parse(second_number, RegionCode::get_unknown()) {
@@ -2945,13 +2966,13 @@ impl PhoneNumberUtil {
/// # Arguments
///
/// * `phone_number` - The string to check.
pub fn is_alpha_number(&self, phone_number: &str) -> bool {
if !self.is_viable_phone_number(phone_number) {
pub fn is_alpha_number<S: AsRef<str>>(&self, phone_number: S) -> bool {
if !self.is_viable_phone_number(phone_number.as_ref()) {
// Number is too short, or doesn't match the basic phone number pattern.
return false;
}
// Copy the number, since we are going to try and strip the extension from it.
let (number, _extension) = self.maybe_strip_extension(&phone_number);
let (number, _extension) = self.maybe_strip_extension(phone_number.as_ref());
return self.reg_exps.valid_alpha_phone_pattern.full_match(number);
}
}

View File

@@ -17,7 +17,7 @@
use log::{error};
use super::regex_util::{RegexFullMatch, RegexConsume};
use crate::{interfaces, phonemetadata::PhoneNumberDesc, regexp_cache::{ErrorInvalidRegex, RegexCache}};
use crate::{interfaces, PhoneNumberDesc, regexp_cache::{ErrorInvalidRegex, RegexCache}};
pub struct RegexBasedMatcher {
cache: RegexCache,

View File

@@ -1,10 +1,10 @@
use protobuf::{Message, MessageField};
use crate::{
enums::{PhoneNumberFormat, PhoneNumberType, NumberLengthType},
errors::{ParseError, ValidationError},
phonemetadata::{NumberFormat, PhoneMetadata, PhoneMetadataCollection, PhoneNumberDesc},
phonenumber::{phone_number::CountryCodeSource, PhoneNumber},
PhoneNumberFormat, PhoneNumberType, NumberLengthType,
ParseError, ValidationError,
NumberFormat, PhoneMetadata, PhoneMetadataCollection, PhoneNumberDesc,
CountryCodeSource, PhoneNumber,
PhoneNumberUtil,
};