Add some phonenumberutil functions
This commit is contained in:
314
Cargo.lock
generated
314
Cargo.lock
generated
@@ -41,6 +41,27 @@ version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "6.1.0"
|
||||
@@ -55,6 +76,37 @@ dependencies = [
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dec_from_char"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5467a30cfe9ac2281f28ab2fc7e82b3036544bcb340f648425769fe9eb737708"
|
||||
dependencies = [
|
||||
"dec_from_char_gen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dec_from_char_gen"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec31e992a6f011b864a5eda50b01cf01fa8d9d53241f4902f93d0f8024faa6"
|
||||
dependencies = [
|
||||
"csv",
|
||||
"quote",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
@@ -128,6 +180,95 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"potential_utf",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_core"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"utf16_iter",
|
||||
"utf8_iter",
|
||||
"write16",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_locale_core",
|
||||
"icu_properties_data",
|
||||
"icu_provider",
|
||||
"potential_utf",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locale_core",
|
||||
"stable_deref_trait",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
@@ -162,6 +303,12 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.13"
|
||||
@@ -203,6 +350,15 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
|
||||
dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
@@ -321,7 +477,9 @@ name = "rlibphonenumbers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"dec_from_char",
|
||||
"fast-cat",
|
||||
"icu_normalizer",
|
||||
"itoa",
|
||||
"log",
|
||||
"protobuf",
|
||||
@@ -329,6 +487,7 @@ dependencies = [
|
||||
"regex",
|
||||
"strum",
|
||||
"thiserror 2.0.12",
|
||||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -363,18 +522,50 @@ version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.1"
|
||||
@@ -408,6 +599,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.20.0"
|
||||
@@ -461,12 +663,34 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "utf16_iter"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
|
||||
|
||||
[[package]]
|
||||
name = "utf8_iter"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
@@ -642,3 +866,93 @@ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "write16"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
"yoke-derive",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
|
||||
dependencies = [
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec-derive"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@@ -22,6 +22,9 @@ itoa = "1.0.15"
|
||||
# concatenation of strings
|
||||
fast-cat = "0.1.1"
|
||||
strum = { version = "0.27.1", features = ["derive"] }
|
||||
icu_normalizer = "2.0.0"
|
||||
tinystr = "0.8.1"
|
||||
dec_from_char = "0.1.1"
|
||||
|
||||
[build-dependencies]
|
||||
thiserror = "2.0.12"
|
||||
|
||||
@@ -72,6 +72,7 @@ fn parse_prefixes(path: &str, prefixes: &mut BTreeMap<i32, String>) -> Result<()
|
||||
|
||||
fn main() -> Result<(), BuildError> {
|
||||
protobuf_codegen::Codegen::new()
|
||||
.pure()
|
||||
.includes(["resources"])
|
||||
.input("resources/phonemetadata.proto")
|
||||
.input("resources/phonenumber.proto")
|
||||
|
||||
@@ -6,7 +6,8 @@ mod phonenumberutil;
|
||||
mod regexp_cache;
|
||||
mod regex_based_matcher;
|
||||
pub mod i18n;
|
||||
pub mod regex_util;
|
||||
pub(crate) mod regex_util;
|
||||
pub(crate) mod string_util;
|
||||
|
||||
/// I decided to create this module because there are many
|
||||
/// boilerplate places in the code that can be replaced with macros,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use core::error;
|
||||
use std::num::ParseIntError;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::regexp_cache::ErrorInvalidRegex;
|
||||
@@ -5,5 +8,38 @@ use crate::regexp_cache::ErrorInvalidRegex;
|
||||
#[derive(Debug, PartialEq, Error)]
|
||||
pub enum PhoneNumberUtilError {
|
||||
#[error("{0}")]
|
||||
InvalidRegexError(#[from] ErrorInvalidRegex)
|
||||
}
|
||||
InvalidRegexError(#[from] ErrorInvalidRegex),
|
||||
#[error("Parse error: {0}")]
|
||||
ParseError(#[from] ParseError),
|
||||
#[error("Extract number error: {0}")]
|
||||
ExtractNumberError(#[from] ExtractNumberError)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Error)]
|
||||
pub enum ParseError {
|
||||
// Removed as OK variant
|
||||
// NoParsingError,
|
||||
#[error("Invalid country code")]
|
||||
InvalidCountryCodeError, // INVALID_COUNTRY_CODE in the java version.
|
||||
#[error("Not a number")]
|
||||
NotANumber,
|
||||
#[error("Too short after idd")]
|
||||
TooShortAfterIdd,
|
||||
#[error("Too short Nsn")]
|
||||
TooShortNsn,
|
||||
#[error("Too long nsn")]
|
||||
TooLongNsn, // TOO_LONG in the java version.
|
||||
#[error("{0}")]
|
||||
InvalidRegexError(#[from] ErrorInvalidRegex),
|
||||
#[error("{0}")]
|
||||
ParseNumberAsIntError(#[from] ParseIntError)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Error)]
|
||||
pub enum ExtractNumberError {
|
||||
#[error("No valid start character found")]
|
||||
NoValidStartCharacter,
|
||||
#[error("Invalid number")]
|
||||
NotANumber,
|
||||
}
|
||||
|
||||
|
||||
31
src/phonenumberutil/helper_types.rs
Normal file
31
src/phonenumberutil/helper_types.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::proto_gen::phonenumber::phone_number::CountryCodeSource;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PhoneNumberWithCountryCodeSource<'a> {
|
||||
pub phone_number: Cow<'a, str>,
|
||||
pub country_code_source: CountryCodeSource
|
||||
}
|
||||
|
||||
impl<'a> PhoneNumberWithCountryCodeSource<'a> {
|
||||
pub fn new(phone_number: Cow<'a, str>, country_code_source: CountryCodeSource) -> Self {
|
||||
Self { phone_number, country_code_source }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PhoneNumberAndCarrierCode<'a> {
|
||||
pub carrier_code: Option<&'a str>,
|
||||
pub phone_number: Cow<'a, str>
|
||||
}
|
||||
|
||||
impl<'a> PhoneNumberAndCarrierCode<'a> {
|
||||
pub fn new<B: Into<Cow<'a, str>>>(carrier_code: Option<&'a str>, phone_number: B) -> Self {
|
||||
Self { carrier_code, phone_number: phone_number.into() }
|
||||
}
|
||||
|
||||
pub fn new_phone<B: Into<Cow<'a, str>>>(phone_number: B) -> Self {
|
||||
Self { carrier_code: None, phone_number: phone_number.into() }
|
||||
}
|
||||
}
|
||||
@@ -4,30 +4,15 @@ mod errors;
|
||||
mod enums;
|
||||
mod phonenumberutil;
|
||||
mod phone_number_regexps_and_mappings;
|
||||
pub(self) mod helper_types;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub use enums::{MatchType, PhoneNumberFormat, PhoneNumberType, ValidationResultErr, ValidNumberLenType};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::phonenumberutil::phonenumberutil::PhoneNumberUtil;
|
||||
// use crate::phonenumberutil::phonenumberutil::PhoneNumberUtil;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ErrorType {
|
||||
#[error("No parsing")]
|
||||
NoParsingError,
|
||||
#[error("Invalid country code")]
|
||||
InvalidCountryCodeError, // INVALID_COUNTRY_CODE in the java version.
|
||||
#[error("Not a number")]
|
||||
NotANumber,
|
||||
#[error("Too short after idd")]
|
||||
TooShortAfterIdd,
|
||||
#[error("Too short Nsn")]
|
||||
TooShortNsn,
|
||||
#[error("Too long nsn")]
|
||||
TooLongNsn, // TOO_LONG in the java version.
|
||||
}
|
||||
|
||||
static PHONE_NUMBER_UTIL: LazyLock<PhoneNumberUtil> = LazyLock::new(|| {
|
||||
PhoneNumberUtil::new()
|
||||
});
|
||||
// static PHONE_NUMBER_UTIL: LazyLock<PhoneNumberUtil> = LazyLock::new(|| {
|
||||
// PhoneNumberUtil::new()
|
||||
// });
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@ impl RegexBasedMatcher {
|
||||
|
||||
// find first occurrence
|
||||
if allow_prefix_match {
|
||||
Ok(regexp.consume_start(phone_number).is_some())
|
||||
Ok(regexp.matches_start(phone_number))
|
||||
} else {
|
||||
Ok(regexp.full_match(phone_number))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use regex::{Captures, Regex};
|
||||
use regex::{Captures, Match, Regex};
|
||||
|
||||
pub trait RegexFullMatch {
|
||||
/// Eq of C fullMatch
|
||||
@@ -8,18 +6,12 @@ pub trait RegexFullMatch {
|
||||
}
|
||||
|
||||
pub trait RegexConsume {
|
||||
/// Eq of C Consume
|
||||
fn consume_start<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> {
|
||||
self.consume_start_capturing(s).map(| res| res.0)
|
||||
fn matches_start<'a>(&self, s: &'a str) -> bool {
|
||||
self.find_start(s).is_some()
|
||||
}
|
||||
|
||||
fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
|
||||
|
||||
fn find_and_consume<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> {
|
||||
self.find_and_consume_capturing(s).map(| res| res.0)
|
||||
}
|
||||
|
||||
fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
|
||||
fn captures_start<'a>(&self, s: &'a str) -> Option<Captures<'a>>;
|
||||
fn find_start<'a>(&self, s: &'a str) -> Option<Match<'a>>;
|
||||
}
|
||||
|
||||
trait RegexMatchStart {
|
||||
@@ -48,24 +40,21 @@ impl RegexMatchStart for Regex {
|
||||
}
|
||||
|
||||
impl RegexConsume for Regex {
|
||||
fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
|
||||
_consume(self, s, true)
|
||||
fn captures_start<'a>(&self, s: &'a str) -> Option<Captures<'a>> {
|
||||
let captures = self.captures(s)?;
|
||||
let full_capture = captures.get(0)?;
|
||||
if full_capture.start() != 0 {
|
||||
return None
|
||||
}
|
||||
|
||||
Some(captures)
|
||||
}
|
||||
|
||||
fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
|
||||
_consume(self, s, false)
|
||||
fn find_start<'a>(&self, s: &'a str) -> Option<Match<'a>> {
|
||||
let found = self.find(s)?;
|
||||
if found.start() != 0 {
|
||||
return None
|
||||
}
|
||||
Some(found)
|
||||
}
|
||||
}
|
||||
|
||||
fn _consume<'a>(
|
||||
r: &Regex, input: &'a str,
|
||||
anchor_at_start: bool
|
||||
) -> Option<(Cow<'a, str>, Captures<'a>)> {
|
||||
let captures = r.captures(input)?;
|
||||
let full_capture = captures.get(0)?;
|
||||
if anchor_at_start && full_capture.start() != 0 {
|
||||
return None
|
||||
}
|
||||
|
||||
Some((Cow::Borrowed(&input[full_capture.end()..]), captures))
|
||||
}
|
||||
36
src/string_util.rs
Normal file
36
src/string_util.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Strips prefix of given string Cow. Returns option with `Some` if
|
||||
/// prefix found and stripped.
|
||||
///
|
||||
/// Calls `drain` if string is owned and returns slice if string is borrowed
|
||||
pub fn strip_cow_prefix<'a>(cow: Cow<'a, str>, prefix: &str) -> Option<Cow<'a, str>> {
|
||||
match cow {
|
||||
Cow::Borrowed(s) => s.strip_prefix(prefix).map(| s | Cow::Borrowed(s)),
|
||||
Cow::Owned(mut s) => {
|
||||
if s.starts_with(prefix) {
|
||||
s.drain(0..prefix.len());
|
||||
return Some(Cow::Owned(s));
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::string_util::strip_cow_prefix;
|
||||
|
||||
#[test]
|
||||
fn test_usage() {
|
||||
let str_to_strip = Cow::Owned("test0:test".to_owned());
|
||||
let stripped = strip_cow_prefix(str_to_strip, "test0");
|
||||
assert_eq!(stripped, Some(Cow::Owned(":test".to_owned())));
|
||||
|
||||
let str_to_strip = Cow::Owned("test:test0".to_owned());
|
||||
let stripped = strip_cow_prefix(str_to_strip, "test0");
|
||||
assert_eq!(stripped, None)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user