Crates.io | rlibphonenumber |
lib.rs | rlibphonenumber |
version | 0.2.1 |
created_at | 2025-07-13 18:41:08.824202+00 |
updated_at | 2025-07-20 17:46:11.554192+00 |
description | A high-performance Rust port of Google's libphonenumber for parsing, formatting, and validating international phone numbers. |
homepage | |
repository | https://github.com/vloldik/rlibphonenumber |
max_upload_size | |
id | 1750677 |
size | 84,725,848 |
A Rust port of Google's comprehensive library for parsing, formatting, and validating international phone numbers.
Built on base libphonenumber 9.0.8 Used metadata version: 9.0.10
This library is a new adaptation of Google's libphonenumber
for Rust. Its primary goal is to provide a powerful and efficient tool for handling phone numbers, with a structure that is intuitively close to the original C++ version.
You might be aware of an existing Rust implementation of libphonenumber
. However, its maintenance has slowed, and I believe that a fresh start is the best path forward. This project aims to deliver a more direct and familiar port for developers acquainted with the C++ or Java versions of the original library.
This library gives you access to a wide range of functionalities, including:
The following benchmarks were run against the rust-phonenumber
crate. All tests were performed on the same machine and dataset. Lower is better.
Format | rlibphonenumber (this crate) | rust-phonenumber | Performance Gain |
---|---|---|---|
E164 | ~668 ns | ~12.82 µs | ~19x faster |
International | ~11.76 µs | ~17.20 µs | ~1.5x faster |
National | ~15.19 µs | ~22.66 µs | ~1.5x faster |
RFC3966 | ~13.41 µs | ~18.59 µs | ~1.4x faster |
Task | rlibphonenumber (this crate) | rust-phonenumber | Performance Gain |
---|---|---|---|
Parse | ~11.60 µs | ~13.45 µs | ~16% faster |
Add rlibphonenumber
to your Cargo.toml
:
[dependencies]
rlibphonenumber = "0.2.1" # Please use the latest version from crates.io
Using the library is straightforward. The PhoneNumberUtil
struct is the main entry point for all operations. For convenience, a thread-safe static instance, PHONE_NUMBER_UTIL
, is provided.
Here is a detailed example that demonstrates how to parse a number, validate it, and format it in several standard ways.
use rlibphonenumber::{
// or instead you can use PhoneNumberUtil::new()
PHONE_NUMBER_UTIL,
PhoneNumberFormat,
};
#[test]
fn main() {
let number_string = "+1-587-530-2271";
let region_code = "US"; // United States
// 1. Parse the number
match PHONE_NUMBER_UTIL.parse(number_string, region_code) {
Ok(number) => {
println!("✅ Successfully parsed number.");
println!(" - Original input: '{}' (in '{}')", number_string, region_code);
println!(" - Country Code: {}", number.country_code());
println!(" - National Number: {}", number.national_number());
// 2. Validate the number
// `is_valid_number` performs a full validation, checking length,
// prefix, and other region-specific rules.
let is_valid = PHONE_NUMBER_UTIL.is_valid_number(&number);
println!("\nIs the number valid? {}", if is_valid { "Yes" } else { "No" });
if !is_valid {
return;
}
// 3. Format the number in different standard formats
let international_format = PHONE_NUMBER_UTIL.format(&number, PhoneNumberFormat::International);
let national_format = PHONE_NUMBER_UTIL.format(&number, PhoneNumberFormat::National);
let e164_format = PHONE_NUMBER_UTIL.format(&number, PhoneNumberFormat::E164);
let rfc3966_format = PHONE_NUMBER_UTIL.format(&number, PhoneNumberFormat::RFC3966);
println!("\nFormatted Outputs:");
println!(" - International: {}", international_format);
println!(" - National: {}", national_format);
println!(" - E.164: {}", e164_format);
println!(" - RFC3966: {}", rfc3966_format);
// 4. Get additional information about the number
let number_type = PHONE_NUMBER_UTIL.get_number_type(&number);
let number_region = PHONE_NUMBER_UTIL.get_region_code_for_number(&number);
println!("\nAdditional Information:");
println!(" - Number Type: {:?}", number_type); // e.g., FixedLine
println!(" - Number Region: {}", number_region); // e.g., US
}
Err(e) => {
// Handle parsing errors, e.g., if the number is invalid or not a number.
println!("❌ Error parsing number: {:?}", e);
}
}
}
✅ Successfully parsed number.
- Original input: '+1-587-530-2271' (in 'US')
- Country Code: 1
- National Number: 5875302271
Is the number valid? Yes
Formatted Outputs:
- International: +1 587-530-2271
- National: (587) 530-2271
- E.164: +15875302271
- RFC3966: tel:+1-587-530-2271
Additional Information:
- Number Type: FixedLineOrMobile
- Number Region: CA
The library is under active development. The core PhoneNumberUtil
is fully implemented and passes the original library's test suite.
The project roadmap includes porting these additional components:
AsYouTypeFormatter
: For formatting phone numbers as a user types.PhoneNumberOfflineGeocoder
: To provide geographical location information for a number.PhoneNumberToCarrierMapper
: To identify the carrier associated with a number.Contributions are highly welcome! Whether you are fixing a bug, improving documentation, or helping to port a new module, your help is appreciated.
To maintain consistency with the original library, this project uses pre-compiled metadata. If you need to regenerate the metadata, for instance, after updating the PhoneNumberMetadata.xml
file, you can use the provided tools.
The tools
directory contains a rewritten Rust-based code generator for the C++ pre-compiled metadata.
To run the code generation process, execute the following script:
./tools/scripts/generate_metadata.sh
This script will:
.rs
files into the src/generated/metadata
directory.You can skip the Java build step by passing the --skip-install
flag, which is useful if no changes were made to the generator itself.
./tools/scripts/generate_metadata.sh --skip-install
This project is licensed under the Apache License, Version 2.0. Please see the LICENSE
file for details.