Rlibphonenumber
A high-performance Rust port of Google's libphonenumber library for parsing, formatting, and validating international phone numbers.
Min supported Rust version is 1.88.0
Built on base libphonenumber 9.0.8 Used metadata version: v9.0.24
Overview
This library is a fresh 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, but adapted for Rust ergonomics.
Key capabilities include:
- Parsing and formatting phone numbers.
- Validating phone numbers for all regions of the world.
- Determining the number type (e.g., Mobile, Fixed-line, Toll-free).
- Serde support (optional).
- Thread-safe and high performance.
Performance
rlibphonenumber is designed for speed. Benchmarks show significant improvements over existing alternatives, particularly in formatting operations.
| 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 |
| Parse | ~11.60 µs | ~13.45 µs | ~16% faster |
Installation
Add rlibphonenumber to your Cargo.toml:
[]
= "0.3.1"
Enabling Serde
To enable Serialize and Deserialize support for PhoneNumber:
[]
= { = "0.3.0", = ["serde"] }
Getting Started
The library exposes a global static PHONE_NUMBER_UTIL, but for most common operations, you can now use methods directly on the PhoneNumber struct.
Complete Example
use ;
Serde Integration
When the serde feature is enabled, PhoneNumber serializes to a string (E.164 format) and can be deserialized from a string.
use PhoneNumber;
use json;
Project Status
The library is under active development. The core PhoneNumberUtil is fully implemented and passes the original library's test suite.
Roadmap:
AsYouTypeFormatter: For formatting phone numbers as a user types.PhoneNumberOfflineGeocoder: To provide geographical location information.PhoneNumberToCarrierMapper: To identify the carrier associated with a number.
Contributing
Contributions are highly welcome! Whether you are fixing a bug, improving documentation, or helping to port a new module, your help is appreciated.
Code Generation
To maintain consistency with the original library, this project uses pre-compiled metadata. If you need to regenerate the metadata (e.g., after updating PhoneNumberMetadata.xml), use the provided script:
Fuzz Testing
Beyond standard unit tests that cover expected behavior, rlibphonenumber undergoes rigorous fuzz testing to ensure its resilience against unexpected, malformed, and potentially malicious input. Given that phone number parsing often deals with untrusted data from users, stability is a primary design goal.
Running the Fuzzer
-
Install prerequisites:
-
Run a fuzz target:
full-cycle: A comprehensive test of the parse -> validate -> format workflow.
To start a fuzzing session, run:
# Example for the main target
Manual Instantiation & Feature Flags
By default, this crate enables the global_static feature, which initializes a thread-safe, lazy-loaded static instance PHONE_NUMBER_UTIL. This allows you to use convenience methods directly on PhoneNumber (e.g., number.is_valid()).
However, if you need granular control over memory usage, wish to avoid global state, or are working in an environment where lazy statics are undesirable, you can disable this feature.
Disabling the Global Instance
In your Cargo.toml, disable the default features:
[]
= { = "0.3.0", = false }
Using PhoneNumberUtil::new()
When global_static is disabled, the PHONE_NUMBER_UTIL constant and the helper methods on PhoneNumber (like .format_as(), .is_valid()) will not be available. You must instantiate the utility manually and pass it around.
⚠️ Performance Note: PhoneNumberUtil::new() compiles regexes upon initialization. This is an expensive operation. Create it once and reuse it (e.g., wrap it in an Arc or pass it by reference).
use ;
License
This project is licensed under the Apache License, Version 2.0. Please see the LICENSE file for details.