Skip to content

Commit 7d03bc9

Browse files
committed
Fit NationalNumber in 64 bits
1 parent 9a909f8 commit 7d03bc9

File tree

2 files changed

+31
-41
lines changed

2 files changed

+31
-41
lines changed

src/national_number.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,25 @@ use std::fmt;
1818
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)]
1919
pub struct NationalNumber {
2020
pub(crate) value: u64,
21+
}
22+
23+
impl NationalNumber {
24+
pub fn new(value: u64, zeros: u8) -> Self {
25+
// E.164 specifies a maximum of 15 decimals, which corresponds to slightly over 48.9 bits.
26+
// 56 bits ought to cut it here.
27+
assert!(value < (1 << 56), "number too long");
28+
Self {
29+
value: ((zeros as u64) << 56) | value,
30+
}
31+
}
2132

33+
/// The number without any leading zeroes.
34+
pub fn value(&self) -> u64 {
35+
self.value & 0x00ffffffffffffff
36+
}
37+
38+
/// The number of leading zeroes.
39+
///
2240
/// In some countries, the national (significant) number starts with one or
2341
/// more "0"s without this being a national prefix or trunk code of some
2442
/// kind. For example, the leading zero in the national (significant) number
@@ -35,18 +53,8 @@ pub struct NationalNumber {
3553
///
3654
/// Clients who use the parsing or conversion functionality of the i18n phone
3755
/// number libraries will have these fields set if necessary automatically.
38-
pub(crate) zeros: u8,
39-
}
40-
41-
impl NationalNumber {
42-
/// The number without any leading zeroes.
43-
pub fn value(&self) -> u64 {
44-
self.value
45-
}
46-
47-
/// The number of leading zeroes.
4856
pub fn zeros(&self) -> u8 {
49-
self.zeros
57+
(self.value >> 56) as u8
5058
}
5159
}
5260

@@ -58,10 +66,10 @@ impl From<NationalNumber> for u64 {
5866

5967
impl fmt::Display for NationalNumber {
6068
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61-
for _ in 0..self.zeros {
69+
for _ in 0..self.zeros() {
6270
write!(f, "0")?;
6371
}
6472

65-
write!(f, "{}", self.value)
73+
write!(f, "{}", self.value())
6674
}
6775
}

src/parser/mod.rs

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ pub fn parse_with<S: AsRef<str>>(
8484
source: number.country,
8585
},
8686

87-
national: NationalNumber {
88-
value: number.national.parse()?,
89-
zeros: number.national.chars().take_while(|&c| c == '0').count() as u8,
90-
},
87+
national: NationalNumber::new(
88+
number.national.parse()?,
89+
number.national.chars().take_while(|&c| c == '0').count() as u8,
90+
),
9191

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

112-
national: NationalNumber {
113-
value: 33316005,
114-
zeros: 0,
115-
},
112+
national: NationalNumber::new(33316005, 0),
116113

117114
extension: None,
118115
carrier: None,
@@ -200,10 +197,7 @@ mod test {
200197
source: country::Source::Number,
201198
},
202199

203-
national: NationalNumber {
204-
value: 64123456,
205-
zeros: 0,
206-
},
200+
national: NationalNumber::new(64123456, 0),
207201

208202
extension: None,
209203
carrier: None,
@@ -221,10 +215,7 @@ mod test {
221215
source: country::Source::Default,
222216
},
223217

224-
national: NationalNumber {
225-
value: 30123456,
226-
zeros: 0,
227-
},
218+
national: NationalNumber::new(30123456, 0),
228219

229220
extension: None,
230221
carrier: None,
@@ -239,10 +230,7 @@ mod test {
239230
source: country::Source::Plus,
240231
},
241232

242-
national: NationalNumber {
243-
value: 2345,
244-
zeros: 0,
245-
},
233+
national: NationalNumber::new(2345, 0,),
246234

247235
extension: None,
248236
carrier: None,
@@ -257,10 +245,7 @@ mod test {
257245
source: country::Source::Default,
258246
},
259247

260-
national: NationalNumber {
261-
value: 12,
262-
zeros: 0,
263-
},
248+
national: NationalNumber::new(12, 0,),
264249

265250
extension: None,
266251
carrier: None,
@@ -275,10 +260,7 @@ mod test {
275260
source: country::Source::Default,
276261
},
277262

278-
national: NationalNumber {
279-
value: 3121286979,
280-
zeros: 0,
281-
},
263+
national: NationalNumber::new(3121286979, 0),
282264

283265
extension: None,
284266
carrier: Some("12".into()),

0 commit comments

Comments
 (0)