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

489
Cargo.lock generated
View File

@@ -11,6 +11,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.19" version = "0.6.19"
@@ -73,18 +79,91 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.1" version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bumpalo"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.1" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [
"anstyle",
"clap_lex",
]
[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]] [[package]]
name = "colog" name = "colog"
version = "1.3.0" version = "1.3.0"
@@ -112,12 +191,73 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "criterion"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"is-terminal",
"itertools",
"num-traits",
"once_cell",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.21" version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crunchy"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]] [[package]]
name = "csv" name = "csv"
version = "1.3.1" version = "1.3.1"
@@ -230,6 +370,12 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.3.3" version = "0.3.3"
@@ -242,6 +388,16 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "half"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.5" version = "0.14.5"
@@ -260,6 +416,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]] [[package]]
name = "home" name = "home"
version = "0.5.11" version = "0.5.11"
@@ -279,12 +441,32 @@ dependencies = [
"hashbrown 0.15.4", "hashbrown 0.15.4",
] ]
[[package]]
name = "is-terminal"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.1" version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"
@@ -315,6 +497,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -327,6 +519,12 @@ version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.15" version = "0.4.15"
@@ -355,12 +553,46 @@ version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "lru-cache"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
dependencies = [
"linked-hash-map",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.5" version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@@ -373,6 +605,18 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "oncemutex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2"
[[package]]
name = "oorandom"
version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.9.11" version = "0.9.11"
@@ -386,6 +630,54 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "phonenumber"
version = "0.3.7+8.13.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2247167dc3741816fdd4d3690e97f56a892a264b44f4c702078b72d1f8b6bd40"
dependencies = [
"bincode",
"either",
"fnv",
"nom",
"once_cell",
"quick-xml",
"regex",
"regex-cache",
"serde",
"serde_derive",
"strum 0.26.3",
"thiserror 1.0.69",
]
[[package]]
name = "plotters"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
[[package]]
name = "plotters-svg"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
dependencies = [
"plotters-backend",
]
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.11.1" version = "1.11.1"
@@ -461,6 +753,15 @@ dependencies = [
"thiserror 1.0.69", "thiserror 1.0.69",
] ]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.40" version = "1.0.40"
@@ -476,6 +777,26 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.13" version = "0.5.13"
@@ -494,7 +815,7 @@ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-automata", "regex-automata",
"regex-syntax", "regex-syntax 0.8.5",
] ]
[[package]] [[package]]
@@ -505,9 +826,27 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-syntax", "regex-syntax 0.8.5",
] ]
[[package]]
name = "regex-cache"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f7b62d69743b8b94f353b6b7c3deb4c5582828328bcb8d5fedf214373808793"
dependencies = [
"lru-cache",
"oncemutex",
"regex",
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.8.5" version = "0.8.5"
@@ -519,16 +858,18 @@ name = "rlibphonenumber"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"colog", "colog",
"criterion",
"dashmap", "dashmap",
"dec_from_char", "dec_from_char",
"env_logger", "env_logger",
"fast-cat", "fast-cat",
"itoa", "itoa",
"log", "log",
"phonenumber",
"protobuf", "protobuf",
"protobuf-codegen", "protobuf-codegen",
"regex", "regex",
"strum", "strum 0.27.1",
"thiserror 2.0.12", "thiserror 2.0.12",
] ]
@@ -570,6 +911,15 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@@ -596,19 +946,53 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.1" version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "strum"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [
"strum_macros 0.26.4",
]
[[package]] [[package]]
name = "strum" name = "strum"
version = "0.27.1" version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
dependencies = [ dependencies = [
"strum_macros", "strum_macros 0.27.1",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
] ]
[[package]] [[package]]
@@ -688,6 +1072,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.18" version = "1.0.18"
@@ -700,6 +1094,16 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.14.2+wasi-0.2.4" version = "0.14.2+wasi-0.2.4"
@@ -709,6 +1113,74 @@ dependencies = [
"wit-bindgen-rt", "wit-bindgen-rt",
] ]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "which" name = "which"
version = "4.4.2" version = "4.4.2"
@@ -721,6 +1193,15 @@ dependencies = [
"rustix 0.38.44", "rustix 0.38.44",
] ]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"

View File

@@ -34,4 +34,14 @@ protobuf-codegen = "3.7.2"
[dev-dependencies] [dev-dependencies]
colog = "1.3.0" colog = "1.3.0"
env_logger = "0.11.8" env_logger = "0.11.8"
criterion = "0.5"
phonenumber = "0.3"
[[bench]]
name = "format_bench"
harness = false
[[bench]]
name = "parsing_bench"
harness = false

View File

@@ -18,6 +18,27 @@ This library gives you access to a wide range of functionalities, including:
* Determining the number type (e.g., Mobile, Fixed-line, Toll-free). * Determining the number type (e.g., Mobile, Fixed-line, Toll-free).
* Providing example numbers for every country. * Providing example numbers for every country.
## Performance
The following benchmarks were run against the `rust-phonenumber` crate. All tests were performed on the same machine and dataset. *Lower is better.*
### Formatting
| Format | rlibphonenumber (this crate) | rust-phonenumber | Performance Gain |
|:---|:---:|:---:|:---:|
| **E164** | **~78 ns** | ~2.59 µs | **~33x faster** |
| **International** | **~1.34 µs** | ~3.21 µs | **~2.4x faster** |
| **National** | **~2.33 µs** | ~4.87 µs | **~2.1x faster** |
| **RFC3966** | **~1.62 µs** | ~3.47 µs | **~2.1x faster** |
### Parsing
| Task | rlibphonenumber (this crate) | rust-phonenumber | Performance Gain |
|:--- |:---:|:---:|:---:|
| **Parse** | **~11.60 µs** | ~13.45 µs | **~16% faster** |
This significant performance advantage is achieved through a focus on minimizing allocations, a more direct implementation path, and the use of modern tooling for metadata generation.
## Current Status ## Current Status
The project is currently in its initial phase of development. The core functionalities are being ported module by module to ensure quality and consistency. The project is currently in its initial phase of development. The core functionalities are being ported module by module to ensure quality and consistency.

76
benches/format_bench.rs Normal file
View File

@@ -0,0 +1,76 @@
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use rlibphonenumber::{PhoneNumberFormat, PHONE_NUMBER_UTIL};
use phonenumber::{
self as rlp,
country::Id::{self, AU}, Mode,
};
type TestEntity = (&'static str, &'static str, Id);
fn setup_numbers() -> Vec<TestEntity> {
vec![("0011 54 9 11 8765 4321 ext. 1234", "AU", AU)]
}
fn convert_to_rlp_numbers(numbers: &[TestEntity]) -> Vec<rlp::PhoneNumber> {
numbers
.iter()
.map(|s| rlp::parse(Some(s.2), s.0).unwrap())
.collect()
}
fn convert_to_rlibphonenumber_numbers(
numbers: &[TestEntity],
) -> Vec<rlibphonenumber::PhoneNumber> {
numbers
.iter()
.map(|s| PHONE_NUMBER_UTIL.parse(s.0, s.1).unwrap())
.collect()
}
fn formatting_benchmark(c: &mut Criterion) {
let numbers = setup_numbers();
let rlp_numbers = convert_to_rlp_numbers(&numbers);
let numbers = convert_to_rlibphonenumber_numbers(&numbers);
let mut group = c.benchmark_group("Formatting Comparison");
let mut test = |format_a: PhoneNumberFormat, format_b: Mode| {
group.bench_function(format!("rlibphonenumber: format({:?})", format_a), |b| {
b.iter(|| {
for number in &numbers {
PHONE_NUMBER_UTIL
.format(black_box(number), black_box(format_a))
.unwrap();
}
})
});
group.bench_function(format!("rust-phonenumber: format({:?})", format_b), |b| {
b.iter(|| {
for number in &rlp_numbers {
rlp::format(black_box(number)).mode(format_b).to_string();
}
})
});
for (number_a, number_b) in rlp_numbers.iter().zip(numbers.iter()) {
assert_eq!(
rlp::format(number_a).mode(format_b).to_string(),
PHONE_NUMBER_UTIL
.format(number_b, format_a)
.unwrap()
);
}
};
test(PhoneNumberFormat::E164, Mode::E164);
test(PhoneNumberFormat::International, Mode::International);
test(PhoneNumberFormat::National, Mode::National);
test(PhoneNumberFormat::RFC3966, Mode::Rfc3966);
group.finish();
}
criterion_group!(benches, formatting_benchmark);
criterion_main!(benches);

73
benches/parsing_bench.rs Normal file
View File

@@ -0,0 +1,73 @@
// benches/parsing_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};
// --- Импорты из вашей библиотеки ---
use rlibphonenumber::PHONE_NUMBER_UTIL;
// --- Импорты из внешней библиотеки ---
use phonenumber::{self as rlp, country::Id};
// Тип для наших тестовых данных: (строкаомера, регион_для_вас, регион_для_rlp)
type TestEntity = (&'static str, &'static str, Id);
/// Подготавливает разнообразный набор данных для тестирования парсинга.
/// Это дает более объективную оценку, чем один номер.
fn setup_parsing_data() -> Vec<TestEntity> {
use phonenumber::country::Id::*;
vec![
// Оригинальный номер из вашего примера
("0011 54 9 11 8765 4321 ext. 1234", "AU", AU),
// Простой номер США в национальном формате
("(650) 253-0000", "US", US),
// Номер Великобритании в международном формате со знаком +
("+44 20 8765 4321", "GB", GB),
// Номер Великобритании с национальным префиксом (ведущий ноль)
("020 8765 4321", "GB", GB),
// Сложный мобильный номер Аргентины
("011 15-1234-5678", "AR", AR),
// Итальянский номер со значащим ведущим нулем
("02 12345678", "IT", IT),
// "Vanity" номер (с буквами)
("1-800-FLOWERS", "US", US),
// Короткий номер, который может быть валидным в некоторых регионах
("12345", "DE", DE),
]
}
fn parsing_benchmark(c: &mut Criterion) {
// Получаем наш набор тестовых данных
let numbers_to_parse = setup_parsing_data();
let mut group = c.benchmark_group("Parsing Comparison");
// --- Бенчмарк для вашей библиотеки rlibphonenumber ---
group.bench_function("rlibphonenumber: parse()", |b| {
// b.iter() запускает код в цикле много раз для замера
b.iter(|| {
// Итерируемся по всем номерам в нашем наборе
for (number_str, region, _) in &numbers_to_parse {
// Вызываем parse, обернув аргументы в black_box.
// Это гарантирует, что компилятор не оптимизирует вызов.
// Мы не используем результат, так как нас интересует только скорость выполнения.
let _ = PHONE_NUMBER_UTIL.parse(black_box(number_str), black_box(region));
}
})
});
// --- Бенчмарк для библиотеки rust-phonenumber ---
group.bench_function("rust-phonenumber: parse()", |b| {
b.iter(|| {
for (number_str, _, region_id) in &numbers_to_parse {
// Аналогичный вызов для второй библиотеки
let _ = rlp::parse(black_box(Some(*region_id)), black_box(number_str));
}
})
});
group.finish();
}
// Макросы для регистрации и запуска бенчмарка
criterion_group!(benches, parsing_benchmark);
criterion_main!(benches);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,7 @@
use log::{error}; use log::{error};
use super::regex_util::{RegexFullMatch, RegexConsume}; 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 { pub struct RegexBasedMatcher {
cache: RegexCache, cache: RegexCache,

View File

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