Skip to content

Commit

Permalink
Merge pull request #52 from whisperfish/compact-national
Browse files Browse the repository at this point in the history
Fit NationalNumber in 64 bits
  • Loading branch information
rubdos authored Dec 14, 2023
2 parents 219248f + 1f46da5 commit 928bb3f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 41 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ doc-comment = "0.3"
rstest = ">= 0.13, <=0.18"
rstest_reuse = "0.6"
anyhow = "1"
criterion = ">=0.4, <=0.5"

[[bench]]
name = "parsing"
harness = false
29 changes: 29 additions & 0 deletions benches/parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};

pub fn criterion_benchmark(c: &mut Criterion) {
let cases = [
"+80012340000",
"+61406823897",
"+611900123456",
"+32474091150",
"+34666777888",
"+34612345678",
"+441212345678",
"+13459492311",
"+16137827274",
"+1 520 878 2491",
"+1-520-878-2491",
];

for case in cases {
c.bench_with_input(BenchmarkId::new("parse", case), &case, |b, case| {
b.iter(|| {
let pn = black_box(case);
phonenumber::parse(None, pn)
})
});
}
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
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 928bb3f

Please sign in to comment.