From 9a13ac810ff6a1de8dfd58a96ac995816f25f917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20F=C3=A9ron?= Date: Tue, 22 Aug 2023 08:18:51 +0200 Subject: [PATCH 1/3] Bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 186ed43..54742a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "phonenumber" -version = "0.3.2+8.13.9" +version = "0.3.3+8.13.9" edition = "2021" rust-version = "1.58.0" From f53e56b0f9222cb358546025ab05967818bc61da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20F=C3=A9ron?= Date: Tue, 22 Aug 2023 08:19:59 +0200 Subject: [PATCH 2/3] Parse mnc and mcc into Carrier --- src/carrier.rs | 38 ++++++++++++++++++++------------------ src/error.rs | 8 ++++++-- src/formatter.rs | 10 +++++++--- src/parser/mod.rs | 8 ++++++-- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/carrier.rs b/src/carrier.rs index b207804..09b1093 100644 --- a/src/carrier.rs +++ b/src/carrier.rs @@ -13,34 +13,36 @@ // limitations under the License. use std::fmt; -use std::ops::Deref; + +use crate::ParseError; /// A phone number carrier. +/// see: https://en.wikipedia.org/wiki/Mobile_country_code#National_operators #[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)] -pub struct Carrier(pub(crate) String); - -impl> From for Carrier { - fn from(value: T) -> Carrier { - Carrier(value.into()) - } +pub struct Carrier { + pub mcc: u16, // always 3 digits + pub mnc: u16, // 2 or 3 digits } -impl Deref for Carrier { - type Target = str; - - fn deref(&self) -> &str { - &self.0 - } -} +impl TryFrom<&str> for Carrier { + type Error = ParseError; -impl AsRef for Carrier { - fn as_ref(&self) -> &str { - &self.0 + fn try_from(value: &str) -> Result { + Ok(Self { + mcc: value + .get(0..3) + .and_then(|c| c.parse().ok()) + .ok_or_else(|| ParseError::InvalidCountryCode)?, + mnc: value + .get(3..) + .and_then(|c| c.parse().ok()) + .ok_or_else(|| ParseError::InvalidNetworkCode)?, + }) } } impl fmt::Display for Carrier { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) + write!(f, "{}{}", self.mcc, self.mnc) } } diff --git a/src/error.rs b/src/error.rs index 35f34d4..5aeb588 100644 --- a/src/error.rs +++ b/src/error.rs @@ -56,12 +56,16 @@ pub enum Parse { #[allow(unused)] // This is unused in the build script NoNumber, - /// The country code supplied did not belong to a supported country or - /// non-geographical entity. + /// The country code supplied is not correct. #[error("invalid country code")] #[allow(unused)] // This is unused in the build script InvalidCountryCode, + /// The network code supplied is not correct + #[error("invalid network code")] + #[allow(unused)] // This is unused in the build script + InvalidNetworkCode, + /// This indicates the string started with an international dialing prefix, /// but after this was stripped from the number, had less digits than any /// valid phone number (including country code) could have. diff --git a/src/formatter.rs b/src/formatter.rs index 4bf694d..63af9be 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -15,7 +15,7 @@ use crate::{ consts, metadata::{Database, Format, Metadata, DATABASE}, - phone_number::PhoneNumber, + phone_number::PhoneNumber, Carrier, }; use std::{borrow::Cow, fmt}; @@ -234,7 +234,7 @@ fn replace( meta: &Metadata, formatter: &Format, transform: Option<&str>, - carrier: Option<&str>, + carrier: Option<&Carrier>, ) -> String { formatter .pattern() @@ -249,7 +249,11 @@ fn replace( .as_str(); let format = transform.replace(*consts::NP, meta.national_prefix().unwrap_or("")); let format = format.replace(*consts::FG, &format!("${}", first)); - let format = format.replace(*consts::CC, carrier.unwrap_or("")); + let format = if let Some(carrier) = carrier.map(|c| c.to_string()) { + format.replace(*consts::CC, &carrier) + } else { + format.replace(*consts::CC, "") + }; consts::FIRST_GROUP.replace(formatter.format(), &*format) } else { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 542bad6..02e5ef4 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::carrier::Carrier; +use std::borrow::Borrow; + use crate::consts; use crate::country; use crate::error; @@ -90,7 +91,10 @@ pub fn parse_with>( }, extension: number.extension.map(|s| Extension(s.into_owned())), - carrier: number.carrier.map(|s| Carrier(s.into_owned())), + carrier: number.carrier.and_then(|s| { + let s: &str = s.borrow(); + s.try_into().ok() + }), }) } From 966f05e5670f3350434e95040af6fc21923ddde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20F=C3=A9ron?= Date: Mon, 4 Sep 2023 09:04:47 +0200 Subject: [PATCH 3/3] Add short test --- src/carrier.rs | 13 +++++++++++++ src/parser/mod.rs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/carrier.rs b/src/carrier.rs index 09b1093..094f202 100644 --- a/src/carrier.rs +++ b/src/carrier.rs @@ -46,3 +46,16 @@ impl fmt::Display for Carrier { write!(f, "{}{}", self.mcc, self.mnc) } } + +#[cfg(test)] +mod test { + use std::convert::TryInto; + use super::Carrier; + + #[test] + fn test_mobile_network_codes() { + assert_eq!(Carrier { mcc: 336, mnc: 1}, "336001".try_into().unwrap()); + assert_eq!(Carrier { mcc: 336, mnc: 35}, "33635".try_into().unwrap()); + } + +} \ No newline at end of file diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 02e5ef4..be7cb8d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -285,7 +285,7 @@ mod test { }, extension: None, - carrier: Some("12".into()), + carrier: "12".try_into().ok(), }, parser::parse(Some(country::BR), "012 3121286979").unwrap() );