Skip to content

Commit

Permalink
Fit NationalNumber in 64 bits
Browse files Browse the repository at this point in the history
  • Loading branch information
rubdos committed Dec 14, 2023
1 parent eec6745 commit f69abee
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 41 deletions.
34 changes: 21 additions & 13 deletions src/national_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,25 @@ use std::fmt;
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)]
pub struct NationalNumber {
pub(crate) value: u64,
}

impl NationalNumber {
pub fn new(value: u64, zeros: u8) -> Self {
// E.164 specifies a maximum of 15 decimals, which corresponds to slightly over 48.9 bits.
// 56 bits ought to cut it here.
assert!(value < (1 << 56), "number too long");
Self {
value: ((zeros as u64) << 56) | value,
}
}

/// The number without any leading zeroes.
pub fn value(&self) -> u64 {
self.value & 0x00ffffffffffffff
}

/// The number of leading zeroes.
///
/// In some countries, the national (significant) number starts with one or
/// more "0"s without this being a national prefix or trunk code of some
/// kind. For example, the leading zero in the national (significant) number
Expand All @@ -36,18 +54,8 @@ pub struct NationalNumber {
///
/// Clients who use the parsing or conversion functionality of the i18n phone
/// number libraries will have these fields set if necessary automatically.
pub(crate) zeros: u8,
}

impl NationalNumber {
/// The number without any leading zeroes.
pub fn value(&self) -> u64 {
self.value
}

/// The number of leading zeroes.
pub fn zeros(&self) -> u8 {
self.zeros
(self.value >> 56) as u8
}
}

Expand All @@ -59,10 +67,10 @@ impl From<NationalNumber> for u64 {

impl fmt::Display for NationalNumber {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for _ in 0..self.zeros {
for _ in 0..self.zeros() {
write!(f, "0")?;
}

write!(f, "{}", self.value)
write!(f, "{}", self.value())
}
}
38 changes: 10 additions & 28 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ pub fn parse_with<S: AsRef<str>>(
source: number.country,
},

national: NationalNumber {
value: number.national.parse()?,
zeros: number.national.chars().take_while(|&c| c == '0').count() as u8,
},
national: NationalNumber::new(
number.national.parse()?,
number.national.chars().take_while(|&c| c == '0').count() as u8,
),

extension: number.extension.map(|s| Extension(s.into_owned())),
carrier: number.carrier.map(|s| Carrier(s.into_owned())),
Expand All @@ -109,10 +109,7 @@ mod test {
source: country::Source::Default,
},

national: NationalNumber {
value: 33316005,
zeros: 0,
},
national: NationalNumber::new(33316005, 0),

extension: None,
carrier: None,
Expand Down Expand Up @@ -200,10 +197,7 @@ mod test {
source: country::Source::Number,
},

national: NationalNumber {
value: 64123456,
zeros: 0,
},
national: NationalNumber::new(64123456, 0),

extension: None,
carrier: None,
Expand All @@ -221,10 +215,7 @@ mod test {
source: country::Source::Default,
},

national: NationalNumber {
value: 30123456,
zeros: 0,
},
national: NationalNumber::new(30123456, 0),

extension: None,
carrier: None,
Expand All @@ -239,10 +230,7 @@ mod test {
source: country::Source::Plus,
},

national: NationalNumber {
value: 2345,
zeros: 0,
},
national: NationalNumber::new(2345, 0,),

extension: None,
carrier: None,
Expand All @@ -257,10 +245,7 @@ mod test {
source: country::Source::Default,
},

national: NationalNumber {
value: 12,
zeros: 0,
},
national: NationalNumber::new(12, 0,),

extension: None,
carrier: None,
Expand All @@ -275,10 +260,7 @@ mod test {
source: country::Source::Default,
},

national: NationalNumber {
value: 3121286979,
zeros: 0,
},
national: NationalNumber::new(3121286979, 0),

extension: None,
carrier: Some("12".into()),
Expand Down

0 comments on commit f69abee

Please sign in to comment.